关闭客户端套接字并保持服务器套接字活

时间:2015-01-06 12:11:27

标签: c sockets

我正在使用TCP套接字建立服务器 - 客户端连接。每当我关闭客户端套接字时,我的服务器也会关闭。但我希望只关闭我的客户端,我的服务器必须等待下一个accept()

服务器端:

{
bind(lfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(lfd, 10);
   while(1)
   {
        cfd = accept(lfd, (struct sockaddr*)NULL, NULL);
   //server must wait here after client closes the connection application code
        close(lfd);
    }
}

客户方:

inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
// ... application code
if(c == 1)
   close(fd);

3 个答案:

答案 0 :(得分:6)

当您accept服务器端时,只为该客户端生成一个新套接字。

当您完成与客户的交易后,您必须 close()该套接字(您的术语中的close(cfd))。您可能shutdown()套接字 - 这将影响套接字在TCP级别的关闭方式。但无论您是否执行shutdown()必须 close(),否则您将泄漏FD。

在您打算不接受任何更多连接之前,您不得close()听取fd(程序中的lfd)。

TLDR:将close(lfd)更改为close(cfd)

答案 1 :(得分:2)

描述符lfd描述的TCP侦听套接字用于等待特定端口的TCP传入连接。调用accept后,会创建一个新的套接字描述符,例如cfd

服务器和客户端之间的所有数据交换都是使用cfd执行的。如果客户端首先关闭套接字,则服务器端可能的sendrecv将返回-1,并带有相应的errno值。

如果您希望服务器关闭连接,则应使用shutdown(cfd, SHUT_RDWR)close(cfd),而不是close(lfd)。这使lfd套接字打开,允许服务器在accept等待下一个传入连接。 lfd应在服务器终止时关闭。

shutdown()提供了更大的灵活性,可以在永久终止通信之前发送或接收剩余数据。

答案 2 :(得分:0)

accept调用将返回连接到客户端的新套接字描述符(cfd在您的代码中),因此当客户端关闭其连接结束时,cfd将被关闭而不是lfd。只要服务器需要,您就可以使用lfd(侦听套接字)来接受连接。还要考虑在客户端代码中关闭(fd)之前调用shutdown。