我正在使用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);
答案 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
执行的。如果客户端首先关闭套接字,则服务器端可能的send
或recv
将返回-1,并带有相应的errno
值。
如果您希望服务器关闭连接,则应使用shutdown(cfd, SHUT_RDWR)
和close(cfd)
,而不是close(lfd)
。这使lfd
套接字打开,允许服务器在accept
等待下一个传入连接。 lfd
应在服务器终止时关闭。
shutdown()
提供了更大的灵活性,可以在永久终止通信之前发送或接收剩余数据。
答案 2 :(得分:0)
accept调用将返回连接到客户端的新套接字描述符(cfd在您的代码中),因此当客户端关闭其连接结束时,cfd将被关闭而不是lfd。只要服务器需要,您就可以使用lfd(侦听套接字)来接受连接。还要考虑在客户端代码中关闭(fd)之前调用shutdown。