2013-08-04 1 views
1

로그인/로그 아웃이 구현 된 단순한 클라이언트/서버 앱이 있습니다. 연결을 누르면 완벽하게 실행되지만 연결을 끊을 때 문제가 발생합니다 (클라이언트 측에서 EOFException을 얻음). 메신저가 스트림의 열악한 폐쇄로 인해 거의 확실합니다. 어떤 힌트?java.io.EOFException (스트림 닫기에 문제가 있음)

java.io.EOFException 
    at java.io.DataInputStream.readByte(DataInputStream.java:98) 
    at java.io.ObjectInputStream.nextTC(ObjectInputStream.java:506) 
    at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:778) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006) 
     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963) 
    at com.mtm.ClientConnection.disconnect(ClientConnection.java:54)** 

클라이언트 클래스 :

public class ClientConnection implements Admin{ 

    public ObjectInputStream in; 
    public static ObjectOutputStream out; 
    public Socket socket; 

    public void connect(){ 

     String host = IP; 
     int port = PORTO; 

     try {  
      socket = new Socket (host,port); 
      out = new ObjectOutputStream(socket.getOutputStream()); 
      in = new ObjectInputStream(socket.getInputStream());   

      MSG_Login login = new MSG_Login();   
      login.setID(DeviceId.getId().toString()); 
      send(login); 

      Object c1 = in.readObject(); 
      if(c1 instanceof MSG_Login){ 
       Thread thread = new ClientThread(this); 
       thread.start(); 
      } 

     } 
     catch (UnknownHostException e) {  e.printStackTrace(); } 
     catch (SocketException e) {    e.printStackTrace(); } 
     catch (IOException e) {     e.printStackTrace(); } 
     catch (ClassNotFoundException e) {  e.printStackTrace(); } 
    } 

    public void disconnect(){ 
     try { 
      MSG_Logout logout = new MSG_Logout(); 
      logout.setID(DeviceId.getId().toString()); 
      send(logout); 

      Object c1 = in.readObject(); 
      if(c1 instanceof MSG_Logout){ 
       in.close(); 
       out.close(); 
       socket.close(); 
      } 
     } 
     catch (IOException e) { e.printStackTrace(); } 
     catch (ClassNotFoundException e) {  e.printStackTrace(); } 
    } 

    public static void send(Object obj) { 
     try { 
      out.writeObject(obj); 
      out.flush(); 
      out.reset(); 
     } 
     catch (IOException e) { e.printStackTrace(); } 
    } 
} 

서버 (스레드) 클래스 : 아무 문제가 없습니다

public class Servidor_Thread extends Thread{ 

    public Socket canal; 
    Servidor serv; 
    ObjectOutputStream oos=null; 
    ObjectInputStream ois=null; 
    private boolean logOff; 

    public Servidor_Thread(Servidor serv) { 
     this.serv = serv; 
     canal = serv.socket; 
     logOff = false; 
    } 

    public void run(){ 
      try { 
       ois=new ObjectInputStream(canal.getInputStream()); 
       oos=new ObjectOutputStream(canal.getOutputStream()); 
       while(logOff==false){ 
        Object obj=ois.readObject();/** Objecto recebido - Reconstrução **/ 
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
        Date date = new Date(); 
        if(obj instanceof MSG_Login){ 
         serv.id_database.add(((MSG_Login) obj).getID()); 
         serv.getLog().appendConsole("["+dateFormat.format(date)+"]..........User "+((MSG_Login) obj).getID()+" connected."); 
         enviar(obj); 
        } 
        if(obj instanceof MSG_Logout){ 
         serv.id_database.remove(((MSG_Logout) obj).getID()); 
         serv.getLog().appendConsole("["+dateFormat.format(date)+"]..........User "+((MSG_Logout) obj).getID()+" disconnected."); 
         enviar(obj); 
         stopThread(); 
        } 
       } 
      } 
      catch (IOException e) {     stopThread();  } 
      catch (ClassNotFoundException e) {  e.printStackTrace(); } 
    } 

    public void stopThread(){ 
     logOff = true; 
     try { 
      ois.close(); 
      oos.close(); 
      canal.close(); 
     } catch (IOException e) { e.printStackTrace(); } 
    } 

    public void enviar(Object obj) { 
     try { 
      oos.writeObject(obj); 
      oos.flush(); 
      oos.reset(); 
     } 
     catch (IOException e) { e.printStackTrace(); } 
    } 
} 

답변

2

여기에 대답. readObject() 메소드는 스트림의 끝에서 EOFException을 던집니다. 이것은 정상적인 동작입니다. 당신은 그것을 잡아라, 당신이 읽고있는 시내를 닫고, 독서 루프를 나와야한다.