통신 기반 2 - 서버 생성

통신 기초를 배운 지 곧 일주일이 된다.서버, 클라이언트의 실현에 이르러 진도가 자연스럽게 느려졌다.
수업 중의 두 가지는 약간의 체험을 느꼈다.
     1.라인 간의 의존 관계를 줄이고
가장 기초적이고 밑바닥의 클래스가 바뀌면 그것을 바탕으로 하는 클래스는 모두 영향을 받기 때문에 의존 관계를 줄인다.
     2.전체적인 프레임 디자인과 디테일을 구분하여 문제를 보완하다
현재 구조 구축을 완성한 것인지, 아니면 구체적인 세부 사항을 보완한 것인지 알 수 있다.
위에서 아래로 디자인을 하고 먼저 유형의 디자인을 완성한 다음에 구체적인 방법을 보완한다.
서버를 먼저 쓰고 클라이언트는 텔넷 명령으로 잠시 생성됩니다.
그 중에서 몇 군데는 비교적 많은 시간을 썼다.
     1.서버가 클라이언트의 메시지를 수신하는 readString 방법
(1) 서버에서 정확한 메시지를 읽습니다.
스스로 정의: 리턴을 누르면 서버에서 메시지를 받습니다.리턴 키를 누르면 바이트 13(리턴 "\r")과 바이트 10(줄 바꿈") 두 바이트를 읽습니다.매번 읽기 입력 흐름 중의 한 문장의 끝 표지는 바이트 13까지 읽는 것이기 때문에 읽는 모든 문장은 지난번에 리턴을 한 후 입력 흐름에서 읽지 않은 줄 바꿈 바이트 10에 남겨 처리해야 한다.
(2) 클라이언트의 오른쪽 상단을 클릭하여 닫을 때 바이트-1을 읽고 입력이 끝나지 않으면 사순환에 들어갈 수 있습니다.서버가 바이트를 읽는 조건을 보완하고 한 마디를 읽는 순환을 뛰어넘습니다.
// ,
	public String readString(java.io.InputStream ins){
	         // StringBuffer
		StringBuffer strb=new StringBuffer();
		
		try{
			int t=ins.read();
			// , 13、10
			// ,t=-1
			while(t!=13 && t!=-1){// , , 
				strb.append((char)t);// Enter , 10 
				t=ins.read();
			}
			String str=strb.toString();
			
			if(t!=-1){// 
				if(str.charAt(0)=='
'){ return str.substring(1, str.length()); }else{// return str; } } }catch(Exception ef){ ef.printStackTrace(); } // , return null; }

클라이언트가 대화의 while 순환을 끝내고 "end"를 입력하여 대화를 종료합니다.
while(!"end".equals(str) && str!=null ){
				System.out.println(" while(end) ");
				// ...... 
				ChatTools.sendMsg2Others(this, str);
				str=readString(ins);
			}

     2.서버 인터페이스를 추가한 후 정상적인 정지 제어가 필요합니다.
작동 중지 기능 설계:
(1) 시작하기 전에 라인을 누르지 않고 휴면 대기,
(2) 부팅 후 서버 생성 성공
(3) 중지 후 서버 종료
순환 실행 (1) (2) (3)
    3.accept에 있을 때, Server Socket 대상을 닫거나,read에 있을 때, Socket 대상을 닫으면 Socket Exception을 포획합니다. 이런 것들은 막힌 상태에서 닫힙니다. 발생하는 이상은 정상적입니다. 피할 수 없습니다.이상을 포착한 후 적당히 처리하면 된다.
    4. 서버를 닫은 후에도 서버는 클라이언트에게 메시지를 보낼 수 있습니다.
이것은 비교적 빨리 해결되었습니다. 서버가 클라이언트의 메시지를 받는 스레드 대상인 ChatThread를 대기열에서 제거하면 됩니다.서버가 대상을 보내지 않았을 때 메시지를 보낼 수 없습니다.
    5. 서버를 닫은 후에도 클라이언트는 서버에 메시지를 보낼 수 있습니다.
문제의 본질은 서버가 클라이언트 메시지를 수신하는 라인이 실행이 끝나지 않았다는 것이다. 즉run 방법이 실행이 끝나지 않았다는 것이다.
(1) 서버의 스레드가 클라이언트의 메시지를 수신하는 데 영향을 줄 줄 줄 알았던 스레드 ChatThread.왜냐하면 스레드 ChatThread는 서버의 스레드에서 생성되기 때문이다.테스트 후에 두 라인은 독립적이며 둘 사이의 끝은 서로 영향을 주지 않는다.
(2) ChatThread 강제 종료
스레드 수량이 알 수 없기 때문에 제어하기 어렵기 때문에 그들을 대기열에 넣고 처리합니다.대열을 제외하고는 당분간 다른 방법을 생각해 내지 못할 것이다.서버가 닫힐 때 모든 Socket 대상을 강제로 닫으면 흐름도 없어집니다.그러면 run 방법이 실행되면 서버에서 클라이언트 메시지를 받을 수 없습니다.
여기서 강조해야 할 것은 각 클래스의 속성과 방법을 명확하게 알고 클래스 간의 관계도를 그려야 한다는 것이다.중복 처리를 피하다.예를 들어 Socket은 ChatThread 클래스의 속성입니다. 대기열arrayList를 만든 후에 ArrayList를 만들 필요가 없습니다.
인터페이스가 있는 서버에 들어가면 진도가 매우 느리다.때로는 때때로 생각을 정리하고 방법이 어떤 기능을 실현해야 하는지를 고려해야 한다.이전의 코드를 되돌아보는 것도 개념을 더욱 잘 이해하는 데 도움이 된다.
코드가 많기 때문에 서버의 생각을 정리했다.
        1. 서버를 만들고,
        2. 서버가 클라이언트 연결을 순환적으로 기다리는 막힌 상태입니다
        3. 클라이언트 연결이 성공하면 연결 대상 Socket을 받습니다(연결 시 사용자 이름, 비밀번호 확인)
        4. Socket 객체에서 입출력 스트림 가져오기
        5. 서버와 클라이언트ct의 대화를 처리합니다
5.1 서버가 클라이언트에게 메시지 보내기
5.2 서버는 클라이언트가 보낸 메시지, 스레드를 수신합니다
5.2.1 새로운 클라이언트를 스레드 대기열에 추가
5.2.2 서버를 통해 다른 클라이언트에게 보내는 클라이언트 메시지
5.2.3 오프라인 클라이언트, 스레드 대기열에서 삭제
       6.서버를 닫고 모든 Socket 객체를 닫고 대기열을 비웁니다.
그 중에서 비교적 많은 대기열 조작을 사용했는데 일반적으로 다음과 같은 조작이 있는데 그 중의 한 단계를 잊어버리면 오류를 찾아야 한다.
      1.대기열 추가
      2.대기열에서 객체 제거
      3.프로그램 종료, 대기열 비우기
이것도 연습을 많이 하고 연습을 하면서 이해하고 공부를 많이 해야 한다.

좋은 웹페이지 즐겨찾기