1

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

我有两个插座 A 和 B。

1)B向A发送了一些数据--> A已读取数据--> A关闭-->当B尝试从A读取一些数据时,它得到-1(或EOF)。

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

请原谅我,如果你不能理解我的问题。请看代码

服务器.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");
        }
    }
}

客户端.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。

4

2 回答 2

0

1)因为B建立了连接,所以A进入CLOSE_WAIT。它将处于该状态,直到 B 关闭连接。没有可读取的内容,因此对 B 的 InputStream 的 read() 调用返回 -1。

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

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

于 2012-12-08T07:50:20.810 回答
0

1)B向A发送了一些数据--> A已读取数据--> A关闭-->当B尝试从A读取一些数据时,它得到-1(或EOF)。

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

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

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

请原谅我,如果你不能理解我的问题。

这里没有问题可以理解。你没有问过问题。您关闭套接字而不发送任何数据,对等方获得 EOS 而不接收任何数据。当对等方正在发送并且对等方收到异常时,您关闭了一个套接字。系统按设计工作。

于 2012-12-08T11:47:37.143 回答