2013-04-30 9 views
1

메인 스레드와 별도의 스레드에서 을 사용하여 TCP 메시지를 읽는 클라이언트를 작성했습니다. 스레드 스택 추적되는 이클립스를 사용하고 있습니다 및 예외가 콘솔에서 발생하지 않지만, 임의의 시간에 디버그 창이 열립니다 내가 가정 무엇에 다음과 같은 오류를 보여이 코드objectinputstream.readobject() 줄 : 사용할 수 없음 [지역 변수를 사용할 수 없음]

Thread[Thread-5](Suspended (exception ThreadDeath)) 
    objectinputstream.readobject() line: not available [local variables unavailable] 
    ReceiveRunnable.run()line:25 
    Thread.run()line:not available 

를 그 예외 포인트 :

class ReceiveRunnable implements Runnable { 
    Object receivedObject; 

    public void run() { 
    while (true) { 
     try {    
     receivedObject = client.objectInStream.readObject(); //line 25 
     } catch (IOException e) { 
     // client.reconnectToServer(); 

     // System.out.println("IO exception in run()"); 
    // System.out.println(e); 
     e.printStackTrace(); 
    } catch (ClassNotFoundException e) { 
    System.out.println("Class Not Found exception in run()"); 
     System.out.println(e); 
    e.printStackTrace(); 
     } catch (Exception e) { 
    System.out.println("Exception in ReceiveRunnable.run()"); 
     System.out.println(e.toString()); 
    e.printStackTrace(); 
     } 
    } 
    } 
} 

client.objectInStreamClient 클래스에서 생성됩니다

void connectToServer(){ 
    try { 
     connected = false; 

     socket = new Socket(host, port); 

     System.out.println("<Connected> " + socket); 

     objectInStream = new ObjectInputStream(socket.getInputStream()); 

     objectOutStream = new ObjectOutputStream(socket.getOutputStream()); 

     receiveThread = new Thread(new ReceiveRunnable(this, "receive")); 

     receiveThread.start(); 

     /* used to periodically ping the server*/ 
     long delay = 0; 
     long period = 5000; 

     connTimer.schedule(clientCheckConnTimerTask, delay, period); 

     connected = true; 

     sendString("[conn]" + clientUUID); 
    } catch (IOException e) { 
     msgBox.set2LineOkMessage("Can not connect to server.", ""); 
     msgBox.show(); 
    } 
} 

사람은 causi이 무엇을 말해 줄 수 문제를 어떻게 해결할 수 있을까요?

답변

1

try 다음에 소켓을 닫고 루프에서 벗어나는 catch (EOFException exc)이없는 경우 코드가 올바르지 않습니다.

같은 소켓에 대해 앞에 항상 ObjectOutputStream을 작성해야합니다. 그렇지 않으면 교착 상태가 발생할 수 있습니다.

+0

필자가 예제에 들려주는 예외를 추가했다. (들여 쓰기가 불편하다. 어떤 이유로 든 올바르게 구문 분석되지 않는다.) 'EOFException'은'IOException'에 걸려 있습니다. 또한 내가 'ObjectOutputStream'과'ObjectInputStream'을 생성하는 순서를 바꿔 놓았습니다. 그러나 이것이 로딩 시간을 빠르게 해준 문제의 원인이라고 생각하지는 않습니다. –

+0

몇 시간 동안 응용 프로그램을 실행 한 채로두고 솔루션이 내 문제를 해결 한 것으로 보입니다. 개체 스트림을 만드는 순서가 중요한 이유를 이해할 수 없습니다. 왜 그런지 설명해 주시겠습니까? –

+0

Javadoc을 참조하십시오. 'ObjectOutputStream'의 생성자는'ObjectInputStream'의 생성자에 의해 읽힌 헤더를 씁니다. 양 끝에서 입력 스트림을 먼저 생성하면 읽지 않아도되므로 양측이 교착 상태가됩니다. 양측이 출력 스트림을 먼저 생성하면 발생하지 않습니다. 양측이 먼저 출력 스트림을 생성하면 상대방의 작업과 상관없이 발생할 수 없습니다. – EJP