为啥当客户端关闭连接时我的简单 C 服务器退出?

Posted

技术标签:

【中文标题】为啥当客户端关闭连接时我的简单 C 服务器退出?【英文标题】:Why my simple C server exits when the client closes connection?为什么当客户端关闭连接时我的简单 C 服务器退出? 【发布时间】:2022-01-22 00:41:39 【问题描述】:
#include <stdio.h>
#include <stdlib.h>     /* exit() */
#include <strings.h>    /* bzero(), bcopy() */
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>

int main(int argc, char **argv)

    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    
    struct sockaddr_in my_addr;
    bzero(&my_addr,sizeof my_addr);
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(9999);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    int res;
    res = bind(sockfd,(struct sockaddr *)&my_addr,sizeof (struct sockaddr_in));
    
    res = listen(sockfd,5);
    
    while (1)      // shouldn't this while cycle "keep alive" the server to wait for new clients?
        struct sockaddr_in cli_addr;
        bzero(&cli_addr,sizeof cli_addr);
        socklen_t cli_size = sizeof (struct sockaddr_in);
        int clisockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&cli_size);

        while (1) 
            char buf[100] = "";
            int b_recv = recv(clisockfd, buf, 100, 0);
            printf("%d %d\n",sockfd,b_recv);
            printf("%s\n",buf);
            char string[] = "test";
            send(clisockfd,string,sizeof string,0))
        
    

如果我用 netcat 测试我的服务器,如果我关闭 netcat,服务器就会退出。为什么?外部while循环不应该让它保持活力吗?为什么以及如何避免服务器关闭?

【问题讨论】:

您使用的几乎所有函数都可能返回错误。你真的需要检查一下! 您永远不允许离开内部while 循环。因此,您要么永远在那里循环,要么发生一些事件,不仅会破坏该循环,还会终止整个程序。如果您希望外循环保持服务器运行,则必须允许某些条件破坏内循环。 【参考方案1】:

如果您仔细检查,当您从客户端关闭连接时,服务器将通过SIGPIPE 信号终止。

发生这种情况是因为您没有检查关闭的连接事件,而是尝试写入关闭的连接。

recv 返回0 时,您不应尝试写入连接的套接字。相反,您应该关闭套接字并跳出内部 recv/send 循环。

while (1) 
    char buf[100] = "";
    int b_recv = recv(clisockfd, buf, 100, 0);
    printf("%d %d\n",clisockfd,b_recv);  // Print the connection socket instead
    if (b_recv <= 0) 
        // Error or closed connection
        close(clisockfd);
        break;  // Go back to the outer loop, wait for new connections
    
    printf("%s\n",buf);
    char string[] = "test";
    send(clisockfd,string,sizeof string,0))

【讨论】:

以上是关于为啥当客户端关闭连接时我的简单 C 服务器退出?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的客户端会杀死我的服务器?

为啥当主应用停止时我的小部件广播接收器服务停止

通过C中的套接字发送IP地址

为啥当未接受的套接字发送消息时,套接字不会抛出错误?

为啥我的 TCP 服务器套接字在一个客户端断开连接后关闭?

为啥当我使用 QImage::scaled() 时我的内存消耗很大?