2017-10-02 2 views
0

Ich erstelle einen einfachen Netzwerk-Client. Es liest eine Textdatei und legt jede Zeile im Netzwerk ab. Am anderen Ende befindet sich ein Server, der die eingehende Leitung liest und mit einer CSV-Textzeile antwortet.Der zweite Socket-Write scheint nicht an das Netzwerk zu senden

Die Ausgangsdatei ich zum Testen bin mit ist einfach:

6216448319, Richard Nixon, Anmelden
6216448319, Richard Nixon, Abmelden

Die Antwort sollte sein "eingeloggt." gefolgt von "Abgemeldet".

Die erste Zeile verarbeitet einwandfrei, aber obwohl die zweite Zeile in den Socket geschrieben scheint, sieht der Server nie eine eingehende Nachricht. Ich habe mein Bestes getan, um der Dokumentation und verschiedenen Online-Tutorials zu folgen, aber nichts, was ich gesehen habe, scheint das gleiche Verhalten zu zeigen. Was vermisse ich?

Wenn ich jede Zeile in einer eigenen Datei sende, reagiert der Server richtig.

protected Integer call() { 
    LOG.info("Starting spooler for file {}, address {}:{}", spoolFile, ipAddress, port); 
    InetAddress server = null; 
    try { 
     server = InetAddress.getByName(ipAddress); 
     LOG.info("IP Address: {}", server.getHostAddress()); 
    } catch (Exception e) { 
     LOG.error("Unknown host: {}", ipAddress, e); 
    } 
    try (Socket socket = new Socket(server, port); 
     BufferedWriter socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
     //PrintWriter socketWriter = new PrintWriter(socket.getOutputStream(), true); 
     BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     BufferedReader fileReader = new BufferedReader(new InputStreamReader(new FileInputStream(spoolFile))) 
    ) { 
     // Read the spool file line by line and put it out on the wire. 
     String line; 
     while ((line = fileReader.readLine()) != null) { 
      if (isCancelled()) { 
       LOG.error("Spool has been cancelled."); 
       break; 
      } 
      line = line.trim(); 
      LOG.info("OUT({}): [{}]", line.length(), line); 
      //Wait until the channel has successfully written out the line. 
      LOG.info("Socket is {} for write.", socket.isConnected() ? "connected" : "not connected"); 
      socketWriter.write(line); 
      socketWriter.flush(); 
      TalkmanMessage outMessage = new TalkmanMessage(line); 
      outMessageList.add(outMessage); 
      // Wait for the network to respond. 
      // Apparently, readline() blocks until a message is received. 
      LOG.info("Waiting for response..."); 
      LOG.info("Socket is {} for read.", socket.isConnected() ? "connected" : "not connected"); 
      String msg = socketReader.readLine(); 
      LOG.info("IN({}): [{}]", msg == null ? null : msg.length(), msg); 
      TalkmanMessage inMessage = new TalkmanMessage(msg); 
      inMessage.setDelay(
        Duration.between(outMessage.getTime(), inMessage.getTime()).toNanos()); 
      inMessageList.add(inMessage); 
      //The readline() seems to leave a non-printing byte in the socket. Read that out. 
      int leftOver; 
      do { 
       LOG.info("Socket is {} for EOL", socket.isConnected() ? "connected." : "not connected"); 
       leftOver = socketReader.read(); 
       LOG.info("Read {} from socket.", leftOver); 
      } while (leftOver > -1); 
     } 
    } catch (Exception e) { 
     LOG.error("Unable to read from file/write to .", e); 
    } 
    return 1; 
} 

Die Logging-Befehle erzeugen die folgende Ausgabe:

OUT(29): [6216448319,Richard Nixon,Log In] 
Socket is connected for write. 
Waiting for response... 
Socket is connected for read. 
IN(12): ["Logged in."] 
Socket is connected for EOL 
Read 13 from socket. S 
Socket is connected for EOL 
Read 10 from socket. 
Socket is connected for EOL 
Read -1 from socket. 
OUT(30): [6216448319,Richard Nixon,Log Out] 
Socket is connected for write. 
Waiting for response... 
Socket is connected for read. IN(null): [null] 
Socket is connected for EOL 
Read -1 from socket. 

Antwort

1
  1. Sie ignorieren Ende des Streams. Sobald read() -1 zurückgegeben hat, ist die Verbindung geschlossen.

  2. Sie liegen falsch, um kontinuierlich zu testen socket.isConnected(). Es wird nicht magisch falsch. Es ist kein Test für Peer-Disconnect.

  3. Sicher sollten Sie Zeilen an den Peer schreiben? d.h. nach dem Senden jeder Zeile newLine() aufrufen?

  4. Und in der Tat sollten Sie nur kopieren Bytes, keine Zeilen lesen, Entfernen/Wiederherstellen von Leitungsabschlüssen, Trimmen, etc. Mit Streams, nicht Leser und Schreiber.

  5. Und wenn Sie Spooling sind, warum erwarten Sie eine Antwort für jede Zeile? Das Wesentliche beim Spoolen ist, dass Sie nur schreiben. Und die Daten, die zurückgegeben werden (unten), weisen in keiner Weise darauf hin, dass es sich um eine Antwort pro Zeile handelt.

  6. Sie scheinen zu versuchen, EOL zu lesen, die bereits von newLine() entfernt wurde. Sieh den Javadoc. Das ergibt keinen Sinn. Und du versuchst es auch, indem du bis zum Ende des Streams liest, in jeder Zeile, die du sendest, was noch weniger Sinn macht.

  7. Was der Server gesendet hat man sich wie folgt:

    IN(12): ["Logged in."]<some line terminator, probably but not certainly CR LF because of below> 
    S <CR><LF> 
    

    Es hat dann die Verbindung geschlossen.

Ich schlage vor, Sie müssen das Anwendungsprotokoll gründlich überprüfen.

+0

Ihr letzter Vorschlag war der Schlüssel.Es gab kein Protokoll per se, aber aufgrund von Einschränkungen in der Vergangenheit erwartete der Server, dass der Socket nach jeder Antwort geschlossen und ein neuer Socket vor jeder Übertragung erstellt wurde. –

+0

Nein. Der Server * schließt * den Socket nach jeder Antwort, nicht nur 'erwartet'. Deshalb hat 'read()' am Client -1 zurückgegeben. – EJP

Verwandte Themen