gpt4 book ai didi

c - ANSI C TCP/IP 服务器在线客户端列表

转载 作者:行者123 更新时间:2023-11-30 17:41:48 26 4
gpt4 key购买 nike

我编写了简单的 TCP/IP 多线程 ANSI C 服务器(客户端是 C Sharp),一切正常,除非服务器没有从客户端接收到正确的信号,它不会结束线程并关闭其套接字(例如,当客户端崩溃时) )。如果这些线程累积,最终可能会成为问题。
我将线程存储在链接列表中 - 迭代它们不是问题。然而,默认情况下它们都被 recv() 阻止,并且由于死客户端不会发送任何内容,因此它们会卡在内存中。

维护在线客户列表的正确方法是什么? (或如何检测连接断开的线程)。

struct tListItem {
pthread_t thisThread;
char* name;
int c_sockfd;
int run;
tListItem* next;
tListItem* prev;};

struct tList{
tListItem* head;
int count;};

线程代码:

while(param->run)
{
bzero(&buf, sizeof(buf));
if ((readLen = recv(param->c_sockfd, buf, BUFFSIZE, 0)) == -1)
{
perror("Read error");
param->run = 0;
}
else if (readLen > 0) {
printf("%s: %s \n", param->name, buf);

parseIncoming(param->c_sockfd, param, buf);}}

这是我尝试检测断开的连接,但这会导致服务器结束且没有消息:

void* maintenance() {
tListItem *item;
char buf[4] = "PNG";
while(1)
{
usleep(2000000);
item= threadList->head;
while(item != 0)
{
if ((send(item->c_sockfd, buf, 3, NULL)) == -1)
{
perror("Write error");
item->run = 0;
}
item = item->next;
}
}

}

最佳答案

有几种常见的处理方法:

  1. 在 TCP 之上的协议(protocol)中实现心跳/乒乓。也就是说,客户端和/或服务器定期向另一端发送心跳消息。如果服务器在一段时间内没有收到任何数据或心跳消息,例如两倍的心跳周期,或者如果服务器发送心跳消息失败,则认为连接已死亡并关闭它。

  2. 实现整体数据超时。每次服务器接收数据时,您都会读取当前时间。您定期检查连接以了解上次接收数据的时间,并超时/关闭一段时间未接收数据的连接。

  3. 启用 TCP keepalive。如果您无法执行 1. 或 2..,这基本上是最后的手段。它将帮助您检测已失效的对等点,因为如果无法到达对等点,TCP 保持事件将中断连接。 (尽管它不会帮助您检测空闲客户端)。请注意,保活的默认值是以小时为单位的。

在所有情况下,您应该始终使用 read()/recv() 或以其他方式监视套接字的读取事件,以便您可以尽快了解连接是否主动中断。

如果您正在执行阻塞 read()/recv() 调用,那么实现这一点也相当困难,您通常需要在 read() 上设置超时,以便您可以定期唤醒并发送心跳消息或检查客户端是否空闲时间过长 - 最好通过使用 select()/poll() 等来完成,这样您就可以获得超时,而不是执行可能永远不会返回的 block read()。

关于c - ANSI C TCP/IP 服务器在线客户端列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20993343/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com