选择说套接字是准备好读的时候肯定没有(实际上已经关闭)

时间:2011-06-23 11:14:51

标签: c network-programming

在我的服务器中,我使用select()检查是否已准备好读取任何套接字以确定它。因此,主循环select()每次迭代时都会执行。

为了测试服务器,我编写了一个简单的客户端,只发送一条消息,然后退出。 BTW。我使用协议缓冲区来发送信息 - 消息表示此库中类型为Message的对象。

测试会话如下:

  1. select()
  2. 服务器的套接字已准备好阅读
  3. accept()客户端套接字
  4. 从客户端套接字读取消息
  5. select()
  6. 服务器的套接字未准备好阅读,客户端已准备就绪
  7. 从客户端套接字读取消息
  8. 最后一步是错误的,因为客户端已经关闭了连接。因此,protobuf库获得Segmentation fault。我想知道为什么FD_ISSET表示套接字在关闭时已在步骤6中准备就绪。如何检查套接字是否已关闭?


    编辑:

    我已经找到了如何检查套接字是否打开

    int error = 0;
    socklen_t len = sizeof (error);
    int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len );
    

2 个答案:

答案 0 :(得分:11)

套接字 “可读”如果远程对等方关闭它,则需要调用recv并处理它返回错误的情况,以及它返回0的情况,表示对等体以有序的方式关闭连接。

读取SO_ERROR sockopt不正确,因为它返回当前待定错误(来自,例如,非阻塞connect

答案 1 :(得分:1)

用于客户端和服务器之间通信的套接字将被标记为可读(即select()将返回)当有数据要读取时,当有EOF要读取时(即同伴关闭了连接。)

当select()返回并且你的fd被标记时,只需读取()。如果read()返回正数,则获得数据。如果它返回0,你就得到了EOF。如果它返回-1,则表示存在问题(除非errno为EAGAIN)。