如何确定是否已关闭与套接字的连接

时间:2011-07-16 01:02:20

标签: c++ linux sockets

我在Linux下使用C ++编写套接字。我有个问题。我怎么知道客户是否关闭了连接。

特别是在服务器接受客户端并开始等待客户端的某些数据的情况下。但客户端不发送任何内容,只关闭与服务器的连接。在这种情况下,我的服务器正在等待一些数据。

以下是我的计划示例:

 newsockfd = accept(sockfd, 
             (struct sockaddr *) &cli_addr, 
             &clilen);
 if (newsockfd < 0) 
      error("ERROR on accept");
 bzero(buffer,256);
 n = read(newsockfd,buffer,255);

我的服务器上也有几个插槽。我需要知道客户端关闭连接的哪个套接字。

3 个答案:

答案 0 :(得分:11)

如果客户关闭了连接,n = read(newsocketfd, buffer, 255)将返回0.

答案 1 :(得分:2)

您可以使用“setsockopt”将套接字设置为超时。您需要#include sys/socket.hsys/types.h

int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); 

您需要SO_RCVTIMEO或SO_SNDTIMEO作为optname。对于optval,你需要一个指向struct timeval的指针,level是SOL_SOCKET。例如:

struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;

setsockopt(mySocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); 

将套接字设置为在10秒后发送操作超时。

答案 2 :(得分:0)

您希望在套接字上使用select或poll,而不仅仅是读取。这样一个慢客户端不会阻止整个服务器。

您还需要跟踪所有插座。

我的多套接口服务器的基本伪代码如下所示:

<create/bind serversocket, listen on it, add it to fd_set>

while ( running )
{
   nd = select( maxfd, fd_set, null, null, timeout )
   if ( nd == 0 )
      continue;  // timeout - do periodic processing
   if ( fd_isset( fd, serversocket )
   {
       do the accept on the server socket and add new socket to the fd_set
   }
   if ( isset( fd, clientsocket ) )
   {
       now you know data is available on the socket, so you can read from it
       a return of 0 on the socket indicates the socket was closed
       in which case you should close your end and remove socket from fd_set
   }
}

我遗漏了很多细节,但这是基本结构。

相关问题