C |套接字未正确关闭

Posted

技术标签:

【中文标题】C |套接字未正确关闭【英文标题】:C | Socket isn't closing correctly 【发布时间】:2018-12-14 02:07:37 【问题描述】:

我目前正在编写一个使用 fork 处理多个连接的服务器。

我正在通过 telnet 对其进行测试。一切正常,但 telnet 没有告诉我连接何时关闭。

这是我的代码:

int main(void) 
    int pop3socket;
    int clientSocket;
    int len;
    int binden;
    int zuhoeren;
    int schliessen;
    int enable=1;
    int pid;
    int pop3_status;
    int server_running = 1;
    /* Infos ueber die Kommunikationspartner :) */
    struct sockaddr_in mailserver;
    struct sockaddr_in pop3client;

    /* Socket erstellen */
    pop3socket = socket(AF_INET, SOCK_STREAM, 0);
    if(pop3socket < 0) 
        perror("Fehler beim Erstellen des Sockets!");
    

    /* IP wiederverwenden */
    if(setsockopt(pop3socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) 
        perror("Fehler beim Wiederverwenden der IP");
    

    /* IP und Port festlegen mithilfe von Bind */
    memset(&mailserver, 0, sizeof(struct sockaddr_in)); 
    mailserver.sin_family = AF_INET;
    mailserver.sin_addr.s_addr = htonl(INADDR_ANY);
    mailserver.sin_port = htons(PORT);
    binden = bind(pop3socket, (struct sockaddr*)&mailserver, sizeof(mailserver));
    if(binden < 0) 

    

    /* Warteschlange einrichten */
    zuhoeren = listen(pop3socket, 5);
    if(zuhoeren == -1) 
        perror("Fehler beim Listen");
    

    /* Verbindung(en) akzeptieren */
    for(;;) 
        len = sizeof(struct sockaddr);
        clientSocket = accept(pop3socket, (struct sockaddr*)&pop3client, &len);

        if(clientSocket < 0) 
            perror("Fehler beim Accepten der Verbindung");
        

        if( (pid = fork()) < 0) 
            perror("Fork fehlgeschlagen");
            exit(8);
         else if(pid == 0) 
            close(pop3socket);
            printf("Prozess: %d\n", getpid());
            /* Begruessen */
            sendSuccessMessage("", clientSocket);
            while(server_running == 1) 
                switch( (pop3_status = (process_pop3(clientSocket, clientSocket))) ) 
                    printf("Status: %d\n", pop3_status);
                    case -1: 
                        server_running = 0;
                        break;
                
            
            if(server_running == 0) 
                printf("Connection beenden\n");
                schliessen = close(clientSocket);
                if(schliessen < 0) 
                    perror("Fehler beim Schließen des Sockets");
                    exit(9);
                
                exit(0);
            
        
    
    return 0;

我的子进程似乎一直在运行并且没有正确结束? 我完全不知道为什么会这样。

这是远程登录输出:

telnet localhost 9999 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
+OK  user joendhard
+OK  pass test123
+OK User logged in. stat
+OK 9 9735 quit
+OK User logged out.

预期输出:

telnet 本地主机 9999 正在尝试 127.0.0.1... 连接到本地主机。 转义字符是 '^]'。 +确定 用户 joendhard +确定 通过测试123 +OK 用户登录。 统计 +确定 9 9735 放弃 +OK 用户退出。

telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK 
user joendhard
+OK 
pass test123
+OK User logged in.
stat
+OK 9 9735
quit
+OK User logged out.
Connection closed by foreign host.

谢谢!

【问题讨论】:

您到底观察到了什么?您应该显示程序和 telnet 会话的输入和输出。 你可以看到我调用了 process_pop3() 直到它返回 -1。之后我尝试关闭连接。 这是否应该调用 process_pop3() 并且两个参数都是同一个套接字? 为什么觉得有问题?显示您的实际输入和输出以及预期输出。 是的@pbn,这是正确的。 【参考方案1】:

客户端套接字在父进程中仍然打开。 fork后在父进程中关闭。

当所有引用套接字文件描述的文件描述符都关闭时,套接字终止连接(通过调用shutdown)。您在此处有 2 个文件 descriptors,指的是客户端套接字文件 description

【讨论】:

那么我必须等待子进程结束,对吧? @L.Kleinmann 不,在父代中分叉后立即关闭它。

以上是关于C |套接字未正确关闭的主要内容,如果未能解决你的问题,请参考以下文章

C中的服务器/套接字编程:数据未正确发送/接收?

C++ Windows 套接字 - 在程序退出时关闭套接字

Python套接字没有正确关闭连接

发送后如何正确关闭套接字(使用 IOCP)?

Linux 中的优雅关闭服务器套接字

在客户端 JAVA 中调用 socket.close() 时,套接字未关闭服务器端