2017-02-06 2 views
0

Warum kann der Client sich nicht mehr mit dem Server verbinden? Wann sollte ich den Socket schließen?Client kann nach der ersten Kommunikation keine Verbindung mit dem Server herstellen TCP

Der erste Client hat die Nachricht gesendet und die Nachricht vom Server empfangen. Alles war in Ordnung. Dann liest der Client etwas aus der Datei und kümmert sich um den Server zu senden. Ich weiß nicht, wo das Problem steht. Liegt das Problem beim Client oder beim Server? Oder schließe ich den falschen Sockel?

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

public class Client { 
public static void main(String[] args) throws IOException { 

    // Connection to Server 
    String serverHostname = "127.0.0.1"; 
    int port = 10007; 

    System.out.println("Attemping to connect to host " + serverHostname 
      + " on port " + port); 

    Socket echoSocket = null; 


    try { 
     echoSocket = new Socket(serverHostname, port); 

    } catch (UnknownHostException e) { 
     System.err.println("Don't know about host: " + serverHostname); 
     System.exit(1); 
    } catch (IOException e) { 
     System.err.println("Couldn't get I/O for the connection to: " 
       + serverHostname); 
     System.exit(1); 
    } 

    // Declare the DataOutput and the DataInput 
    PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(
      echoSocket.getInputStream())); 

    String msgIn, msgOut; 

    msgOut = "TEST"; 

    out.println(msgOut); 

    msgIn = in.readLine(); 
    System.out.println("RETURN: " + msgIn); 
    msgOut = "l"; 
    out.println(msgOut); 
    msgIn = in.readLine(); 
    System.out.println("RETURN: " + msgIn); 
    // Close all connections 
    out.close(); 
    in.close(); 
    echoSocket.close(); 
} 

}

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

    public class Server { 
    public static void main(String[] args) throws IOException { 
    ServerSocket serverSocket = null; 

    try { 
     serverSocket = new ServerSocket(10007); 
    } catch (IOException e) { 
     System.err.println("Could not listen on port: 10007."); 
     System.exit(1); 
    } 

    Socket clientSocket = null; 
    System.out.println("Waiting for connection....."); 

    try { 
     // The socket accepted by the client 
     clientSocket = serverSocket.accept(); 
     System.out.println("Accept connection from " 
       + clientSocket.getLocalAddress().toString() + ":" 
       + clientSocket.getPort()); 

    } catch (IOException e) { 
     System.err.println("Accept failed."); 
     System.exit(1); 
    } 

    System.out.println("Connection successful"); 
    System.out.println("Waiting for input....."); 

    // Get input and output streams associated with the socket. 

    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(
      clientSocket.getInputStream())); 

    String msgIn, msgOut; 

    msgIn = in.readLine(); 

    System.out.println("Server IN: " + msgIn); 

    msgOut = msgIn + " OK "; 

    out.println(msgOut); 

    out.close(); 
    in.close(); 
    clientSocket.close(); 
    serverSocket.close(); 
} 

}

  Attemping to connect to host 127.0.0.1 on port 10007 
     RETURN: TEST OK 
    Exception in thread "main" java.net.SocketException: Software caused connection abort: recv failed 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.socketRead(Unknown Source) 
at java.net.SocketInputStream.read(Unknown Source) 
at java.net.SocketInputStream.read(Unknown Source) 
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source) 
at sun.nio.cs.StreamDecoder.implRead(Unknown Source) 
at sun.nio.cs.StreamDecoder.read(Unknown Source) 
at java.io.InputStreamReader.read(Unknown Source) 
at java.io.BufferedReader.fill(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at Client.main(Client.java:45) 
+0

Können Sie Ihrer Frage eine Beschreibung des Protokolls hinzufügen, das der Client und der Server verwenden (oder verwenden sollen), um miteinander zu kommunizieren? Andernfalls ist es buchstäblich unmöglich zu bestimmen, ob der Client und/oder Server das richtige Protokoll implementieren, das für den Code benötigt wird. Warum schließt der "Server" weiterhin den hörenden Sockel? –

+0

Tcp-Protokoll. Es ist mein erster Tag, an dem ich mit dem Computernetzwerk arbeite. – Boris

+0

Nein, ich meine nicht das Netzwerkprotokoll, ich meine das Anwendungsprotokoll. Die, die der Client und der Server verwenden, um miteinander zu kommunizieren. (Anwendungsprotokolle sind Dinge wie HTTP, FTP, SMTP usw., die definieren, wie die Information codiert wird, wo sie beginnt und endet, wie die Verbindung heruntergefahren wird und so weiter.) Wenn Sie der Meinung sind, dass Sie TCP verwenden können, ohne genau zu definieren, welche Bytes ausgetauscht werden sollen und wie die Nachrichten markiert sind, funktioniert Ihr Code * nur * zufällig. –

Antwort

0

Wenn Sie Programm schreiben, das TCP zu kommunizieren, müssen sie einige Anwendungsebene-Protokoll kommunizieren mit. Wenn eine Seite eine Nachricht an die andere sendet, muss das Protokoll angeben, wie das Ende der Nachricht markiert ist und welche Bytes die Nachricht enthält und was sie bedeuten.

Beispiele für solche Protokolle sind SMTP (zum Senden von E-Mails), HTTP (zum Senden von Webseiten) und FTP (zum Senden von Dateien). Jeder von ihnen hat ein schriftliches Dokument, das erklärt, welche Bytes ausgetauscht werden, was sie bedeuten und wie Sender und Empfänger sie kodieren und parsen sollen.

Ohne eine solche Spezifikation ist es unmöglich herauszufinden, ob Server und Client das tun, was sie tun sollen, weil das Konzept "was sie tun sollen" noch nicht gebildet wurde.

Sehen Sie sich die vorhandenen Protokollspezifikationen an und schreiben Sie eine für das Protokoll, das Ihr Server und Ihr Client verwenden. Dann können Sie überprüfen, ob der Server und der Client das Protokoll erfüllen, um sie zu debuggen.

Dies wird beim ersten Mal schwierig, aber nach ein paar Mal wird es einfacher. Es ist wichtig, zuverlässige Netzwerksoftware zu schreiben. Sie können nur durch Glück ohne ein spezifisches Protokoll Erfolg haben.

TCP ist ein Byte-Stream-Protokoll, kein Nachrichtenprotokoll. Ihre Anwendungen versuchen, Nachrichten zu senden und zu empfangen. Daher benötigen Sie ein Nachrichtenprotokoll auf Anwendungsebene, um festzulegen, wie sie das ausführen. Dann müssen Sie Code zum Senden und Empfangen von "Nachrichten" schreiben, wie vom Protokoll auf Anwendungsebene definiert. Ohne es zu versuchen, versuchen Sie das Unmögliche - versuchen, Nachrichten ohne Code zu senden, der eine Ahnung hat, was eine "Nachricht" eigentlich ist.

Zum Beispiel könnte Ihr Protokoll eine "Nachricht" als "eine Gruppe von Bytes, die keine Zeilenumbrüche oder keine Bytes enthalten, die durch einen Zeilenumbruch abgeschlossen werden" definieren. Dann könnten Sie Code schreiben, um eine "Nachricht" zu senden, indem Sie am Ende eine neue Zeile einfügen und Code, um eine "Nachricht" zu empfangen, indem Sie Teile von Bytes abrufen und nach Zeilenenden scannen. Aber du hast das nicht getan.

+0

Aber warum beim ersten Mal hat es funktioniert? – Boris

+0

@Boris Woher weißt du, dass es das erste Mal ohne ein Protokoll funktioniert hat, das angibt, was es bedeutet, dass es "funktioniert"? Du weißt nicht, was es tun soll! Warum denkst du, was auch immer passiert ist? (Wahrscheinlich funktionierte es buchstäblich aus Versehen. Optimierungen in TCP verursachen oft das Zusammenhalten von Bytes. Aber solcher Code ist * sehr * zerbrechlich und * oft * scheitert zum schlimmstmöglichen Zeitpunkt und fast immer in ungewöhnlichen Umgebungen.) –

+0

Weil der erste Zeit Client "Nachricht" zurückgegeben zurück. Ich möchte das gleiche wieder passieren – Boris

Verwandte Themen