이전에이 소켓 클라이언트와 서버 코드의 일부의 일에 작성하지만,뿐만 아니라 오류를 조사 할 시간이 없었다, 코드를 작성하는 문제도 인식하지 못하고있다, 하나 개의 태도, 그 세부 사항에 대한 깊은 이해를했지만, 질문이 노출되지 않아야하므로 사업의 순서뿐만 아니라 도킹 측 도킹 코드는 선 상황에서 표시되지 않습니다.
첫째, 소켓 BIO 연습을 단일 스레드 서버입니다 수행하여,이 방법은 한편 합 요청을 수신 할 수있는 서버로 이어질 것입니다, 성능은 매우 가난하다
지금은 BIO 포스트 코드를 보면, 가난한 학생들은 참조 할 수 있습니다
서버
공공 클래스 SocketIO { // 클라이언트 코드, 클라이언트와 서버는 특별한 디코딩을 수행하지 않고, 서버 프로세스를 같은 인코딩 전송 개인 정적 최종 . "UTF-8"문자열 CLIENTENCODEING = ; 개인 정적 최종 INT PORT = 7777 ; 개인 정적 AtomicInteger의 = COUNT 새로운 새로운 AtomicInteger ()의를, 공용 정적 무효 메인 (문자열 [] 인수)이 발생 IOException이 { ServerSocket의 ServerSocket로는 = 새로운 새 상기 ServerSocket의 (포트) 에서 System.out.println는 ( "포트 시작"+ 포트) 그동안 (참으로 ) { 소켓 소켓 = 널 ; InputStream 인 inputStream을 = 널 ; OutputStream에 OutputStream에 = 널 ; 은 try는 { // 차단 데이터, 즉 데이터가 이벤트 트리거 방식 콜 수용 받아들이지 // 연결이 오면 번째 (가), 스레드가 더 이상 다시 대기에 동의하는 단일 스레드 또한, 다음과 같은 읽기에서 차단 계속할 수 있기 때문에 연결, 오지 수 소켓 = ; serverSocket.accept () INT ccount = count.incrementAndGet (); 에서 System.out.println ( "새로운 클라이언트가 접속되고, 전류 번호"+ ccount + ""+ 는 System.currentTimeMillis ()); inputStream을 = 새로운 BufferedInputStream을 (socket.getInputStream ()); 의 OutputStream = 새 의 BufferedOutputStream (socket.getOutputStream ()); // 读取正文内容 바이트 [] = 플러시 새로운 바이트 [1024 ]; INT의 길이 = 0 ; 된 StringBuffer REC = 새 의 StringBuffer (); 반면 ((길이 = inputStream.read (플러시)) = -1! ) { rec.append ( 새로운 문자열 (높이, 0 , 길이)); } //필기구 2 // 클라이언트 socket.shutdownOutput ()를 오프 통지되지 않고,이 방법에 따라, 상기 방법은 판독 다이 폐쇄 사이클에 통지하지 않지만 // 가능 () 방법은 제 1 데이터 스트림 전에 알 수있는 판독 및 기록 작업이를 얼마나 많은 바이트하여 읽을 수 있습니다 // 하지만 클라이언트가 문제가 될 수 일괄 전송하는 경우, 데이터 수집 및 이후의 두 번째 배치하지 않을 수 있습니다 // 는 클라이언트 연락하는 것이 좋은 약 // INT COUNT = 0; // 그동안 (COUNT == 0) { // 카운트 = inputStream.available는 (); // } // 바이트 [] = 플러시 새로운 새 바이트 [COUNT]; // InputStream.read (플러시); // 문자열 문자열 새로운 새 REC = (0, CLIENTENCODEING를 플러시 카운트 ); 위로 스트링 = "["+ ccount + "]"+ UUID.randomUUID () + "" ] 에서 System.out.println ( "수신 된 데이터"+ rec.toString () + "돌아 대한 데이터"+ 위로); // 리턴 데이터 OutputStream.write (back.getBytes (), 0 , back.getBytes () 길이.) outputStream.flush (); } 캐치 (예외 E) { e.printStackTrace (); } 최종적으로 { 닫기 (소켓 , 대한 InputStream의 OutputStream); } } } 개인 정적 무효 가까운 (소켓 소켓, 의 InputStream inputStream을, 의 OutputStream의 OutputStream)가 발생 IOException가 { 경우 ! (OutputStream에 = 널 (null) ) { outputStream.close (); } 경우 (inputStream을! = null의 ) { inputStream.close (); } 경우 (소켓 =! 널 (null) ) { socket.close (); } } }
열 몇 점은주의가 필요합니다 :
읽기 방법으로 읽기 (1)는, 바람직하게는 클라이언트의 컨텐츠, 사용할 수있는 코드가 나는 클라이언트가 메시지가 신뢰할 수없는 여러 번 전송 잃게됩니다 발견하는 경우가 전송됩니다.
2 * 스트림 버퍼의 InputStream 버퍼링 된 스트림에 의해 최적이되는 OutputStream을 사용한다
3, 쓰기 후 세척 기억
4 스트림을 닫
클라이언트
// 服务端编码 개인 정적 최종 문자열 SERVERENCODEING = "UTF-8" ; 공공 정적 무효 메인 (문자열 []에 args) { 위해 ( int로 ; 나는 = 0 <1 난 ++ ) { 새로운 스레드 - (()> { 시도 { ) DOO를 ( } 캐치 () {IOException이 전자를 e.printStackTrace을 ( ); } }) (시작).; } } 공공 정적 무효 DOO ()를 발생{IOException이 소켓 소켓 = 널 ; 에서의 InputStream = 널 (null) ; OutputStream에 OUT = 널 (null) ; 문자열 MSG = "좋은 안녕 안녕 안녕!" ; 은 try { // 데이터를 보낼 소켓 = 새로운 새로운 (, 7777 "127.0.0.1"소켓을 ) ; OUT = 새로운 새 의 BufferedOutputStream 제 (Socket.getOutputStream ()) 에서 = 새로운 새 BufferedInputStream을 (Socket.getInputStream ()); out.write (Msg.getBytes ()); out.flush (); out.write ( "약간" .getBytes ()); out.flush (); // // 가까운 입력 스트림 및 출력 스트림 () 중 닫기 아니라 소켓을 야기하고 서버가 수신 할 수없는 원인이됩니다 -1 // out.close (); socket.shutdownOutput는 (); // 텍스트 내용 읽기 바이트 [] = 플러시 새로운 새 바이트 [1,024 ] INT의 길이 = 0 ; StringBuffer와 REC = 새로운 새 의 StringBuffer (); 그동안을 (( ! = in.read 길이 (플러시)) = -1 ) { rec.append ( 새로운 새 문자열 (플러시 0, 길이 SERVERENCODEING)); //표준 코딩 서버 전송에서 {) } 에서 System.out.println ( "客户端收到回复:"+ rec.toString ()); 넣다(); socket.close (); } 캐치 (IOException이 전자) { e.printStackTrace (); } 마지막으로 { (소켓에서, 아웃) 가까운; } } 개인 정적 무효 가까운 (소켓 소켓, 의 InputStream inputStream을, 의 OutputStream의 OutputStream)가 발생 IOException이는 { 경우 ! (OutputStream에 = 널 outputStream.close (); } 경우 (inputStream을! = null의 ) { inputStream.close (); } 경우 (소켓 =! 널 (null) ) { socket.close (); } }
열 몇 점은주의가 필요합니다 :
1 out.close ()는 임의의 입력 스트림 및 출력 스트림 닫기 () 소켓 닫기 확대를 야기되지만 회전을받을 수없는 서비스에 이르게 -1
2 socket.shutdownOutput ()를 사용하여 상기 서버에 의해 전송 된 통지 완료
3, 쓰기 후 세척 기억
4 스트림을 닫