2011-07-16 88 views
2

我在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); 

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

+0

我不明白“客户端关闭连接到哪个套接字”?你需要“newsockfd”的价值吗? – badawi

回答

10

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

2

你可以设置一个插座使用“setsockopt的”超时。你需要#包括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,您需要一个指向结构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秒后发送操作超时。

+5

超时并不表示客户端关闭了套接字。 – badawi

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 
    } 
} 

我留下了很多的细节,但是这是最基本的结构。

+0

-1。不回答这个问题。 – EJP

+0

如果你遵循上面的结构,那么当一个套接字上有一个事件(比如被关闭)时,isset(fd,clientsocket)将为true,并且读取将返回0(EOF) - 我会特别提到在代码中(你显然不打算阅读)。这是一个简单的结构,用于处理服务器套接字和多个客户端套接字,并对它们上的事件作出反应。 – TazMainiac

相关问题