【问题标题】:Socket does not throw exception when trying to write to closed connection尝试写入已关闭的连接时,套接字不会抛出异常
【发布时间】:2014-01-31 17:47:15
【问题描述】:

我是 Java 套接字编程的新手,但我遇到了问题。
当我尝试写入在客户端意外关闭的连接时,我没有得到任何异常。 我有服务器端。

    public static void main(String[] args) throws IOException { 
    ServerSocket socket = new ServerSocket(8036);
    String st;
    while(true) {
        System.out.println("hello");
        Socket socket1 = socket.accept();
        BufferedReader reader = new BufferedReader(new InputStreamReader (socket1.getInputStream()));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
        System.out.println(reader.readLine());
        writer.write("h");
        writer.flush();
    }
}

和客户

    public static void main(String[] args) throws  Exception{

    Inet4Address s = (Inet4Address)Inet4Address.getByName("localhost");
    System.out.println("begin");
     Socket socket = new Socket(s,8036);
     BufferedWriter w = new BufferedWriter (new OutputStreamWriter(socket.getOutputStream()));
     BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
     String h ;
     int prev = 0;
}

您可以看到客户端在连接后立即退出,我什至没有关闭套接字,只是尝试对意外退出的客户端进行建模。但是,在尝试写入套接字时,我没有在服务器端遇到异常。为什么?

【问题讨论】:

  • 我猜这是某种并发问题。您的服务器在一段时间内接受(true),因此当客户端关闭时,您的服务器已经继续前进并正在接受新的连接。
  • 您认为如何在服务器代码中写入套接字?实际上,如果客户端关闭底层套接字,reader.readerLine() 应该会失败,而这正是我尝试运行您的代码时发生的情况。
  • @jarnbjo reader.readerLine() - 在我的情况下只返回 null 而不会抛出 IOException。但为什么呢?
  • @OleksandrPapchenko 因为对方已经关闭了连接。

标签: java sockets


【解决方案1】:
  1. TCP 在收到 FIN 时无法知道对等方已关闭连接以供读取。它只知道对端已经关闭了写入的连接。它可能已经关闭了输出连接,但仍在读取。所以第一次写入这样的连接不会出错。

  2. 当您写入 TCP 连接时,数据会在套接字发送缓冲区中本地缓冲,并将控制权返回给应用程序。写入网络是异步进行的。因此,第一次写入已被对等方关闭的连接不太可能检测到这一点。后续写入会。

注意,您的问题是关于写入已被对等方关闭的连接,而不是写入已关闭的套接字。这将立即为您提供 EBADF。

【讨论】:

  • 这条评论拯救了我的一天。感谢您的回复。
猜你喜欢
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 2013-10-10
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多