在我的服务器中,我使用select()
检查是否已准备好读取任何套接字以确定它。因此,主循环select()
每次迭代时都会执行。
为了测试服务器,我编写了一个简单的客户端,只发送一条消息,然后退出。 BTW。我使用协议缓冲区来发送信息 - 消息表示此库中类型为Message的对象。
测试会话如下:
select()
accept()
客户端套接字select()
最后一步是错误的,因为客户端已经关闭了连接。因此,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 );
答案 0 :(得分:11)
套接字 “可读”如果远程对等方关闭它,则需要调用recv
并处理它返回错误的情况,以及它返回0的情况,表示对等体以有序的方式关闭连接。
读取SO_ERROR
sockopt不正确,因为它返回当前待定错误(来自,例如,非阻塞connect
)
答案 1 :(得分:1)
用于客户端和服务器之间通信的套接字将被标记为可读(即select()将返回)当有数据要读取时,或当有EOF要读取时(即同伴关闭了连接。)
当select()返回并且你的fd被标记时,只需读取()。如果read()返回正数,则获得数据。如果它返回0,你就得到了EOF。如果它返回-1,则表示存在问题(除非errno为EAGAIN)。