如何确定Java中是否有服务器关闭连接(收到RST数据包)?

时间:2012-03-29 16:37:04

标签: java sockets tcp

我正在使用Socket类进行TCP连接。但我目前的问题是确定完全断开原因。 在这两种情况下(如果存在连接超时或服务器关闭连接),我收到带有“Broken pipe”消息的SocketException。那么我如何确切地确定断开原因呢?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为你应该得到一个不同的Exception抛出。如果您正在讨论连接,那么您应该从主机获取SocketException,如果您的连接超时,则会发送重置(我认为这是RST数据包)和SocketTimeoutException。 / p>

如果您再谈论IO,如果服务器断开连接,您将获得SocketException,而如果IO超时(可能只是读取),您将获得SocketTimeoutException。< / p>

这是我使用的测试程序。当然,我正在疯狂地插入插座。

    try {
        new Socket().connect(new InetSocketAddress(someIpThatHangs, 8000), 1000);
        fail("Should have thrown");
    } catch (SocketTimeoutException e) {
        // we expected it to timeout
    }
    try {
        new Socket().connect(new InetSocketAddress(someIpThatResets, 1000));
        fail("Should have thrown");
    } catch (SocketException e) {
        // we expected it to throw an exception immediately on reset
    }

    // start our server
    final ServerSocket serverSocket = new ServerSocket();
    int serverPort = 8000;
    InetSocketAddress address = new InetSocketAddress("127.0.0.1", serverPort);
    serverSocket.bind(address);
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Socket clientSocket = serverSocket.accept();
                    System.err.println("Got a connection");
                    Thread.sleep(1000);
                    clientSocket.close();
                } catch (InterruptedException e) {
                    return;
                } catch (Exception e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    });
    thread.start();

    // wait for the server to start
    Thread.sleep(100);
    Socket clientSocket = new Socket();
    clientSocket.connect(address);

    try {
        // read until the server closes the connection
        clientSocket.getInputStream().read();
    } catch (SocketException e) {
        // expected socket exception
    }

    clientSocket = new Socket();
    clientSocket.connect(address);
    clientSocket.setSoTimeout(100);

    try {
        // read until the socket timeout expires
        clientSocket.getInputStream().read();
    } catch (SocketTimeoutException e) {
        // expected read timeout exception
    }

    serverSocket.close();
    thread.interrupt();