【问题标题】:Client/Server Program: Connection Reset客户端/服务器程序:连接重置
【发布时间】:2013-05-06 10:59:45
【问题描述】:

我编写了一个基本程序来演示客户端服务器交互。连接正在建立,但无法从流中获取数据。它抛出一个异常说明连接重置

服务器

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    private ServerSocket serverSocket;
    private int port;

    public SocketServer(int port) {
        this.port = port;
    }

    public void start() throws IOException {
        System.out.println("Starting the socket server at port:" + port);
        serverSocket = new ServerSocket(port);

        System.out.println("Waiting for clients...");
        Socket client = serverSocket.accept();

        sendWelcomeMessage(client);
    }

    private void sendWelcomeMessage(Socket client) throws IOException {
        BufferedWriter writer = new BufferedWriter(new                        OutputStreamWriter(client.getOutputStream()));
        writer.write("Hello. You are connected to a Simple Socket Server. What is your   name?");
        writer.flush();
    }

    /**
    * Creates a SocketServer object and starts the server.
    *
    * @param args
    */
    public static void main(String[] args) {
        // Setting a default port number.
        int portNumber = 9990;

        try {
            // initializing the Socket Server
            SocketServer socketServer = new SocketServer(portNumber);
            socketServer.start();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户

 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
 import java.net.Socket;
 import java.net.UnknownHostException;

public class SocketClient {

private String hostname;
private int port;
Socket socketClient;

public SocketClient(String hostname, int port){
    this.hostname = hostname;
    this.port = port;
}

public void connect() throws UnknownHostException, IOException{
    System.out.println("Attempting to connect to "+hostname+":"+port);
    socketClient = new Socket(hostname,port);
    System.out.println("Connection Established");
}

public void readResponse() throws IOException{
    String userInput;
    BufferedReader stdIn = new BufferedReader(new InputStreamReader(socketClient.getInputStream()));

    System.out.println("Response from server:");
    while ((userInput = stdIn.readLine()) != null) {
        System.out.println(userInput);
    }
}

public static void main(String arg[]){
    //Creating a SocketClient object
    SocketClient client = new SocketClient ("localhost",9990);
    try {
        //trying to establish connection to the server
        client.connect();
        //if successful, read response from server
        client.readResponse();

    } catch (UnknownHostException e) {
        System.err.println("Host unknown. Cannot establish connection");
    } catch (IOException e) {
        System.err.println("Cannot establish connection. Server may not be up."+e.getMessage());
e.printStackTrace();
    }
}
}

##OUTPUT##

Attempting to connect to localhost:9990
Connection Established
Response from server:
Hello. You are connected to a Simple Socket Server. What is your name?
       java.net.SocketException: Connection reset
    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 SocketClient.readResponse(SocketClient.java:31)
    at SocketClient.main(SocketClient.java:45)

【问题讨论】:

  • 1) 为了尽快获得更好的帮助,请发帖 SSCCE。 2) 将catch (Exception e) { .. 形式的代码更改为catch (Exception e) { e.printStackTrace(); // very informative! .. 3) 始终复制/粘贴错误和异常输出。 4) 对代码块使用一致且符合逻辑的缩进。代码的缩进是为了帮助人们理解程序流程。

标签: java sockets io


【解决方案1】:

当前的实现至少有一个问题。您使用 readLine() 获取数据 - 但是 readLine() 这样做:

读取一行文本。行被视为由换行符 ('\n')、回车符 ('\r') 或回车符后紧跟换行符中的任何一种来终止。

您发出数据的程序不使用换行符来终止“消息”:

writer.write("Hello. You are connected to a Simple Socket Server. What is your name?");
writer.flush();

要终止消息,请添加换行符:

writer.write("Hello. You are connected to a Simple Socket Server. What is your name?");
writer.write("\n");              // shown separately for clarity
writer.flush();

【讨论】:

  • 但在它打印输入数据后不久。它仍然会引发异常。我该如何避免它
  • @user2186265:实际上,我不相信我的答案是正确的——我写的一个快速测试表明readLine() 在连接关闭之前返回了流中的数据。要真正调试它,我们需要查看正在生成的真正异常,正如 Andrew 所指出的那样。答案已被编辑,仅指出换行符的问题。
  • 我修好了。这是因为我使用 while 循环从服务器获取输入,因此它会无限迭代直到连接停止。如果它是正确的,我不会。但是暂时解决了这个问题。而且我仍然担心服务器会在客户端通知之前关闭 TCP 连接。
【解决方案2】:

实际上我也为此苦苦挣扎了一段时间,但我相信我找到了更准确的答案,并认为我应该分享它。原始示例从不关闭BufferedWriter。所以只需在writer.flush() 之后添加writer.close(),如下所示:

writer.write("Hello. You are connected to a Simple Socket Server. What is your name?");
writer.flush();
writer.close();

因为它从未关闭,所以输出永远不会为空,所以while 循环永远不会失败。

【讨论】:

  • 没有。因为它从未关闭,readLine() 从未在对等方返回 null。这与输出为空不同。它不为空。该声明没有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多