2009-03-23 6 views
0

Ich mache einen Prototyp-Client & Server, so dass ich verstehen kann, wie man Wiederverbindungen zu behandeln. Der Server sollte eine Server-Socket erstellen und für immer hören. Ein Client kann eine Verbindung herstellen, seine Daten senden und seinen Socket schließen, aber es wird keine Meldung vom Typ "Ich bin erledigt" an den Server gesendet. Aus diesem Grund erhält der Server eine EOFException, wenn es eine readByte() seit dem Remote-Client geschlossen hat. Im Fehlerhandler für die EOFException wird es den Socket schließen und einen neuen öffnen.Java: Reconnection auf einem Socket gibt manchmal Fehler

Hier ist das Problem: Der Client bekommt manchmal eine SocketWriteError, wenn es den Aufruf outputStream.write() macht, auch nachdem es den Socket/inputstream/outpustream erfolgreich geöffnet hat. Es kann etwas mit der Häufigkeit zu tun haben, dass ich diese Buchsen öffne und schließe. Eine interessante Sache ist, dass der Client eine willkürliche Anzahl von Schreibvorgängen ausführt/schließt/wieder verbindet, bevor er fertig wird. Es wird manchmal bei der ersten Wiederverbindung fehlschlagen, andere Male werden 50 Wiederverbindungen benötigt, bevor man die SocketWriteError sieht.

Hier ist der Fehler auf der Client-Seite:

 
java.net.SocketException: Connection reset by peer: socket write error 
     at java.net.SocketOutputStream.socketWrite0(Native Method) 
     at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) 
     at java.net.SocketOutputStream.write(SocketOutputStream.java:115) 
     at bytebuffertest.Client.main(Client.java:37) 

Hier sind einige Code-Schnipsel:

SERVER:

public static void main(String[] args) 
{ 
    Server x = new Server(); 
    x.initialize(); 
} 

private void initialize() 
{ 
    ServerSocket s; 
    InputStream is; 
    DataInputStream dis; 
    while (true) //ADDED THIS!!!!!!!!!!!!!!!!!!!!!! 
    { 
     try 
     { 
      s = new ServerSocket(4448); 
      s.setSoTimeout(0); 
      s.setReuseAddress(true); 
      is = s.accept().getInputStream(); 
      System.out.println("accepted client"); 
      dis = new DataInputStream(is); 
      try 
      { 

       byte input = dis.readByte(); 
       System.out.println("read: " + input); 
      } catch (Exception ex) 
      { 
       System.out.println("Exception"); 
       dis.close(); 
       is.close(); 
       s.close(); 
      } 
     } catch (IOException ex) 
     { 
      System.out.println("ioexception"); 
     } 
    } 
} 

CLIENT:

public static void main(String[] args) 
{ 
    Socket s; 
    OutputStream os; 
    try 
    { 
     s = new Socket("localhost", 4448); 
     s.setKeepAlive(true); 
     s.setReuseAddress(true); 
     os = s.getOutputStream(); 
     int counter = 0; 
     while (true) 
     { 
      try 
      { 
       os.write((byte) counter++); 
       os.flush(); 

       os.close(); 
       s.close(); 

       s = new Socket("localhost", 4448); 
       s.setKeepAlive(true); 
       s.setReuseAddress(true); 
       os = s.getOutputStream(); 
      } catch (Exception e) 
      { 
       e.printStackTrace(); 
       System.err.println("ERROR: reconnecting..."); 
      } 
     } 
    } catch (Exception ex) 
    { 
     ex.printStackTrace(); 
     System.err.println("ERROR: could not connect"); 
    } 
} 

niemanden weiß wie man richtig wieder verbinden?

Antwort

3

Schließen Sie den ServerSocket nicht bei einem Fehler, nur .accept() eine neue Verbindung.

Was ich normalerweise mache, ist jedes Mal, wenn ServerSocket.accept() einen Socket zurückgibt, spawne ich einen Thread ab, um mit dem Senden und Empfangen von diesem Socket umzugehen. Auf diese Weise können Sie sofort eine neue Verbindung akzeptieren, sobald sich jemand mit Ihnen verbinden möchte.

+0

Ja, ich glaube, das ist die Antwort. Vielen Dank! – jbu