2017-02-06 12 views
0

Почему клиент не может подключиться снова к серверу? Когда мне нужно закрыть сокет?Клиент не может подключиться снова к серверу после первого соединения TCP

Первый клиент отправил сообщение и получил сообщение с сервера. Все было хорошо. Затем клиент читает что-то из файла и отправляется на сервер. Я не знаю, где проблема. Проблема с клиентом или сервером? Или я закрываю неправильный сокет?

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

Можете ли вы добавить к своему вопросу описание протокола, который клиент и сервер используют (или должны использовать) для связи друг с другом? В противном случае, в буквальном смысле, невозможно определить, реализует ли клиент и/или сервер правильный протокол, который необходим для работы кода. Кроме того, почему «сервер» продолжает закрывать прослушивающий сокет? –

+0

Протокол Tcp. Это мой первый день, когда я работаю с компьютерной сетью – Boris

+0

Нет, я не имею в виду сетевой протокол, я имею в виду протокол приложения. Один клиент и сервер используют для связи друг с другом. (Протоколы приложений такие, как HTTP, FTP, SMTP и т. Д., Которые определяют, как кодируется информация, где она начинается и заканчивается, как закрывается соединение и т. Д.) Если вы считаете, что можете использовать TCP без четкого определения байтов, подлежащих обмену, и как будут отмечены сообщения, ваш код будет * никогда * работать, кроме как случайно. –

ответ

0

При написании программы, которые используют протокол TCP для связи, они должны общаться с помощью какой-то протокол прикладного уровня. Если одна сторона отправит сообщение другому, протокол должен указать, как будет помечен конец сообщения, и какие байты будут содержать сообщение и что они означают.

Примерами таких протоколов являются SMTP (используется для отправки электронной почты), HTTP (используется для отправки веб-страниц) и FTP (используется для отправки файлов). Каждый из них имеет письменный документ, в котором объясняется, какие байты обмениваются, что они означают и как отправители и получатели должны кодировать и анализировать их.

Без такой спецификации невозможно определить, делают ли ваш сервер и клиент то, что они должны делать, поскольку концепция «того, что они должны делать» еще не сформирована.

Ознакомьтесь с существующими спецификациями протокола и напишите один для протокола, который использует ваш сервер и клиент. Затем вы можете проверить, соответствуют ли сервер и клиент протоколу для их отладки.

Это будет сложно в первый раз, когда вы это сделаете, но через несколько секунд это станет проще. Очень важно написать надежное сетевое программное обеспечение. Вы можете добиться успеха только в случае отсутствия указанного протокола.

TCP - это протокол потока байтов, а не протокол сообщений. Ваши приложения пытаются отправлять и получать сообщения, поэтому вам нужен протокол сообщений на уровне приложений, чтобы определить, как они это сделают. Затем вам нужно написать код для отправки и получения «сообщений», как это определено протоколом уровня приложения. Без этого вы пытаетесь сделать невозможное - пытаетесь отправить сообщения без кода, который вообще не знает, что такое «сообщение».

Например, ваш протокол может определять «сообщение» как «группу байтов, не содержащих строк новой строки или нулевых байтов, завершенных новой строкой». Затем вы можете написать код для отправки «сообщения», поместив в конец новую строку и код, чтобы получить «сообщение», извлекая фрагменты байтов и просматривая их для строк новой строки. Но вы этого не сделали.

+0

Но почему в первый раз это сработало? – Boris

+0

@Boris Как вы знаете, что он «работал» в первый раз без какого-либо протокола, который указывает, что значит для него «работать»? Вы не знаете, что он должен делать! Почему вы считаете, что с ним случилось? (Вероятно, это работало буквально случайно. Оптимизация в TCP часто приводит к тому, что байты случаются, чтобы слипаться друг с другом, но такой код * очень * хрупкий и * часто * терпит неудачу в самое худшее время и почти всегда в необычных условиях.) –

+0

Потому что первый клиентское «сообщение» времени возвращается. Я хочу повторить то же самое. – Boris

 Смежные вопросы

  • Нет связанных вопросов^_^