Java - 关闭套接字会产生不同的结果

时间:2012-12-08 05:56:49

标签: java sockets networking tcp socketexception

在另一个套接字关闭的同时尝试从套接字读取时,我得到了不同的结果。

我有两个插座A和B.

1)B将一些数据发送给A - > A已阅读数据 - >关闭 - >当B试图从A读取一些数据时,它会得到-1(或EOF)。

2)B将一些数据发送给A - > A甚至在读取数据之前就关闭了 - >现在B尝试从A读取,抛出异常(java.net.SocketException“软件导致连接中止。”)

如果您无法理解我的问题,请原谅。请参阅代码

Server.java

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


class SocketCloser extends Thread
{
    private Socket c;
    public SocketCloser(Socket c) {
        this.c = c;
    }

    public void run()  {

        try{
            this.c.close();
        } catch (Exception e) {}
    }
}


public class Server
{
    public static void main(String argv[]) throws Exception {
        ServerSocket listen = new ServerSocket(6789);

        Socket socket = listen.accept();
        SocketCloser sc = new SocketCloser(socket);
        InputStream is = socket.getInputStream();
        // uncomment below line to get "Software caused connection abort" on client
        //sc.start();
        try {
            Thread.sleep(1000);
            int i = is.read();
            System.out.println("read returned: " + i);
            socket.close();
        } catch (Exception e) {
            System.out.println(e.toString() + " thrown");
        }
    }
}

Client.java

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

public class Client
{
    public static void main(String argv[])
    {
        Socket cSocket;
        try {
            cSocket = new Socket("localhost", 6789);
            InputStream is = cSocket.getInputStream();
            OutputStream os = cSocket.getOutputStream();
            Thread.sleep(1000);
            os.write(200);
            Thread.sleep(1000);
            int i = is.read();
            System.out.println("read returned: " + i);
            cSocket.close();
        } catch (Exception e) {
            System.out.println(e.toString() + " thrown");
        }
    }
}

有人可以帮我弄清楚为什么在一个案例中有例外,在另一个案件中有-1。有趣的是,在Linux上,两个案例都导致-1。

2 个答案:

答案 0 :(得分:0)

1)因为B建立了连接,所以A转到CLOSE_WAIT。它将处于该状态,直到B关闭连接。没有什么可读的,所以B的InputStream上的read()调用返回-1。

2)A在接受电话中被阻止。另一个线程试图关闭套接字,但它不能,因为接受阻止它。当B连接时,接受解除阻塞并且套接字完全关闭。当B试图读取时,套接字不再存在,所以你得到了异常。

我简化了一点,但这就是它的要点。

答案 1 :(得分:0)

  

1)B将一些数据发送给A - > A已阅读数据 - >关闭 - >当B试图从A读取一些数据时,它会得到-1(或EOF)。

我同意。你有什么期望?这是预期的行为。

  

2)B将一些数据发送给A - > A甚至在读取数据之前就关闭了 - >现在B尝试从A读取,抛出异常(java.net.SocketException“软件导致连接中止。”)

我同意。这是在这种不正确情况下的预期行为之一。你有什么期望?

  

如果你无法理解我的问题,请原谅。

这里毫无疑问需要理解。你没有问过一个问题。关闭套接字而不发送任何数据,并且对等方获取EOS而不接收任何数据。在对等方发送时关闭套接字并且对等方获得异常。系统按设计工作。