首先写入远程关闭的套接字不会触发异常,可以吗?爪哇 [英] First write to a remotely-closed socket does not trigger exception, can it? Java

查看:39
本文介绍了首先写入远程关闭的套接字不会触发异常,可以吗?爪哇的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在任何地方都找不到令人满意的答案.可以了解内部原理的人可以解释一下吗?

I have not been able to find a satisfying answer to this question anywhere. Could someone with an understanding of the internals please explain this?

我编写了一个简单的客户端/服务器来演示此问题.服务器读取一行文本,然后关闭套接字.客户端写一行文本,等待10秒钟,然后再写两行文本.第二次写入(10秒后)失败,但第一次写入总是成功.

I wrote a simple client/server to demonstrate this issue. The server reads one line of text then closes the socket. The client writes one line of text, waits 10 seconds, then writes two more lines of text. The second write (after 10 seconds) fails but the first write always succeeds.

为什么BufferedWriter不能在第一次写入时抛出异常?毕竟所有插座在很长一段时间之前都已正常关闭.该代码还在第一次写操作之前就在套接字上进行了读取,返回-1以表明输入端已经检测到套接字关闭.为什么输出端也不知道这一点?

Why can't the BufferedWriter throw an exception on the first write itself? After all the socket was normally closed a long time before. The code also does a read on the socket right before the first write, returns -1 to show that the input side has already detected the socket close. Why can't the output side also know this?

  public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(9000);
        Socket s = ss.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        System.out.println(in.readLine());
        s.close();
        System.out.println("Socket closed");
    }
  }

  public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket s = new Socket("localhost", 9000);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        out.write("Hello, World!\n"); out.flush();
        Thread.sleep(10000);
        System.out.println("Read from socket returns: " + s.getInputStream().read());
        out.write("First write\n"); out.flush();
        System.out.println("First write succeeded without detecting socket closed");
        out.write("Second write\n"); out.flush();
        System.out.println("Second write succeeded without detecting socket closed");
    }
  }

推荐答案

远程关闭与远程关闭无法区别.在这两种情况下,此端均接收FIN,这意味着对等方已停止发送.没有迹象表明他已经停止接收,即使实际上他已经关闭输入.因此,发送方可以检测到的唯一方法是在发送时获取RST,根据定义,除非在发送的数据大于套接字发送缓冲区的情况下,否则在第一次发送时就不会发生这种情况.

A remote close is indistinguishable from a remote shutdown for output. This end receives a FIN in both cases, meaning the peer has stopped sending. There is no indication that he has stopped receiving, even in fact if he has shutdown for input. So the only way the sender can detect is by getting an RST on sending, and that can't happen on the first send, by definition, unless maybe the sent data is larger than the socket send buffer.

这篇关于首先写入远程关闭的套接字不会触发异常,可以吗?爪哇的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆