2014-02-05 3 views
0

자바 소켓을 사용하여 채팅 응용 프로그램을 작성하려고합니다. 서버가 클라이언트의 첫 번째 단계로 들어 오면 클라이언트의 포트에서 클라이언트가 수신하는 개념입니다. 사용자 이름과 클라이언트의 이름으로 저장합니다. 링크 소켓은 sockettuple (사용자 이름이 string이고 소켓이 소켓 임) .. 저장 후 클라이언트가 연결됩니다. 서버가 listenthread과 의 통신을 클라이언트에서 수신 대기합니다. 소켓의 주 스레드에서 발생하고 서버에 쓰기 별도의 스레드에서 소켓 튜플의 저장이 잘 발생 하지만 메시지를 보내는에 f 클라이언트 Socketclosed exception에 롬 서버는 에 모두 서버 쓰기를 발생하고 클라이언트의는 ......Java 소켓 예외 소켓

// mainserver.java 

import java.net.*; 
import java.io.*; 


class listenthread extends Thread{ 
​ServerSocket mserver; 
​Socket link,targetsocket; 
​String user,targetuser; 
​sockettuple targettuple,starray[]= new sockettuple[10]; 
​ 
​ 
​int i=0; 
​ 
​public listenthread(ServerSocket mserver){ 
​try{ 
​System.out.println("Inside Listenthread constructor"); 
​ this.mserver=mserver; 
​ 
​ 
​} 
​catch (Exception e){ 
​System.out.println("Exception inside listenthread constructor"+e); 
​} 
​ 
​} 
​public void run(){ 
​try{ 
​ 
​ while(true){ 
​ 
​ System.out.println("Listening....."); 
​ link=mserver.accept(); 
​ 
​ System.out.println("Accepted"); 
​ BufferedReader intosockb = new BufferedReader(new InputStreamReader(link.getInputStream())); 
​ user= intosockb.readLine(); 
​ 
​ 
​ System.out.println(user + "Accepted"); 
​ 
​ starray[i] =new sockettuple(link,user); 
​ i++; 
​ System.out.println(starray[i-1].username); 
​ 
​ ​new servwrite(link).start(); 
​ ​ 
​ ​intosockb.close(); 
​ ​ 
​ } 
​ 
​} 
​catch(Exception e){ 
​System.out.println("Exception inside listenthread run "+e); 
​e.printStackTrace(); 
​} 
​} 
​} 


class servwrite extends Thread{ 
​Socket link; 
​ 
​public servwrite(Socket link){ 
​this.link=link; 
​} 
​public void run(){ 
​try{ 
​PrintStream fromserv=new PrintStream(link.getOutputStream()); 
​ fromserv.print("You are connected...Enter the target user:"); 
​ ​ 
​} 
​catch(Exception e){ 
​System.out.println("Exception inside run of serv write thread..."+e); 
​} 
​} 
} 
​ 
public class mainserver { 
​ 
​public static void main(String args[]){ 
​try{ 
​ 
​ServerSocket Servermain= new ServerSocket(4579); 
​ 
​System.out.println(" Server main Socket created"); 
​ 
​new listenthread(Servermain).start(); 
​ 
​ 
​ 
​ 
​} 
​catch(Exception e){ 
​System.out.println("Exception inside main "+e); 
​} 
​ 
} 
} 



//Clientmenu.java 

import java.net.*; 
import java.io.*; 

class clientread extends Thread{ 
​Socket client; 
​BufferedReader key=null; 
​public clientread(Socket client){ 
​try{ 
​this.client=client; 
​ key= new BufferedReader(new InputStreamReader(client.getInputStream())); 
​} 
​catch(Exception e){ 
​System.out.println("Exception inside client read thread's constructor"); 
​e.printStackTrace(); 
​} 
​ 
​} 
​public void run(){ 
​try{ 
​System.out.println("First line inside run of client read thread before cmsg readline"); 
​String cmsg= key.readLine(); 
​System.out.println(cmsg); 
​} 
​catch(Exception e){ 
​System.out.println("Exception inside run of client read thread..."+e); 
​e.printStackTrace(); 
​} 
​} 
} 

public class Clientmenu { 
​ 
    public static void main(String args[]){ 
    ​String user=" "; 
    ​String targetuser=""; 
    ​Socket newclient; 
    ​BufferedReader fromtheserv; 

    ​try{ 
    ​ 
    ​newclient = new Socket("127.0.0.1",4579); 
    ​System.out.print("Enter username:"); 
    ​BufferedReader key= new BufferedReader(new InputStreamReader(System.in)); 
     ​user=key.readLine(); 
     ​ 
     ​PrintStream fromclientp=new PrintStream(newclient.getOutputStream()); 
    ​ fromclientp.print(user); 
    ​ 

    ​new clientread(newclient).start(); 
    ​ 
    ​ 
     ​ 
    ​ 
    ​ 

    ​fromclientp.close(); 
    ​ 
    ​ 
    ​ 
    ​ 
    ​ 
      } 
    ​ 
    ​catch(Exception e){ 
    ​System.out.println("Exception inside CLientmenu "+e); 
    ​} 
} 
} 
+1

전체 코드를 덤핑하고 해결하도록 요청하는 것은 여기에 질문하는 좋은 방법이 아닙니다. 관련 코드 만 게시하십시오. –

답변

2

'소켓이 닫혀'스레드를 읽고 당신이 소켓을 폐쇄하고 그것을 계속 사용 것을 의미한다. 코드의 버그입니다.

이 아님을 유의하십시오.은 피어가 연결을 종료했음을 의미합니다.

코드에 많은 문제점이 있으며, 여기에서 검토 할 항목이 너무 많습니다. 그것은 매우 품질이 좋지 않습니다. 자바 튜토리얼의 커스텀 네트워킹 트레일 (Custom Networking Trail)을 얻고 연구하고, 예외 처리에 대한 베스트 프랙티스를 둘러 볼 것을 제안한다. 현재 당신은 일정한 예외를 잡아서 기록하고, 그들이 일어나지 않았던 것처럼 계속합니다. 'catch'블록 이후의 코드는 'try'블록에서 발생한 것에 의존하면 안됩니다.

+3

@downvoter 설명해주세요. – EJP

+0

맞습니다.이 문제에 직면했을 때 실제로 버그였습니다. – Sibish

2

listenThread에서 "Buffered reader"를 닫고 clientMenu에서 "PrintStream"을 닫으면 문제가 발생합니다. 반환 된 입/출력 스트림을 닫으면 기본 소켓도 닫힙니다.

Refer to the documentation here

나는이 문제가 해결되기를 바랍니다.

0

listenthread 클래스의 run 메서드에서이 줄을 제거해보십시오.

intosockb.close(); 

소켓을 닫고있는 스트림을 닫습니다.