【问题标题】:ANSI C TCP/IP server online client listANSI C TCP/IP 服务器在线客户端列表
【发布时间】:2014-01-26 10:00:57
【问题描述】:

我编写了简单的 TCP/IP 多线程 ANSI C 服务器(客户端是 C 语言),一切正常,除非服务器没有从客户端接收到正确的信号,它不会结束线程并关闭其套接字(例如当客户端崩溃时) )。如果这些线程累积,最终可能会成为问题。
我将线程存储在链接列表中 - 遍历它们不是问题。但是,默认情况下它们都被 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;
        }
}

}

【问题讨论】:

  • 我建议发布一些实际代码。我猜这会促进更好的反应。

标签: c multithreading sockets tcp


【解决方案1】:

有几种常见的处理方法:

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

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

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

在所有情况下,您都应该始终处于 read()/recv() 或以其他方式监视套接字的读取事件,以便在连接主动中断时尽快学习。

如果你正在阻塞 read()/recv() 调用,这也很难实现,你通常需要在 read() 上设置一个超时,这样你就可以定期唤醒并发送心跳消息或检查客户端是否空闲太久 - 最好使用 select()/poll() 或类似方法来完成,这样您就可以获得超时而不是执行可能永远不会返回的块 read()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 2015-08-29
    • 1970-01-01
    相关资源
    最近更新 更多