C | Сокет не закрывается правильно - PullRequest
0 голосов
/ 05 июля 2018

В настоящее время я пишу сервер, который использует fork для обработки более 1 соединения.

Я тестирую его через 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:

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 localhost 9999 Попытка 127.0.0.1 ... Подключен к localhost. Escape-символ '^]'. + OK пользователь joendhard + OK пройти тест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.

Спасибо!

1 Ответ

0 голосов
/ 05 июля 2018

Клиентский сокет все еще открыт в родительском процессе. Закройте его в родительском процессе после fork.

Сокет завершает соединение (вызывая shutdown), когда все файлы дескрипторы , относящиеся к файлу сокета описание , закрыты. У вас есть 2 файла дескрипторы здесь, ссылающиеся на файл сокета клиента description .

...