плохой файловый дескриптор сокета

Я хочу написать многоклиентскую сокет-программу,
но получаю неверный файловый дескриптор на этапе принятия.
Как я могу исправить свой код? Спасибо!

Вот мой код
http://codepad.org/q0N1jTgz
Спасибо!
Вот моя часть кода!

while(1)
{
    struct sockaddr_in client_addr;
    int addrlen = sizeof(client_addr);

    /*Accept*/
    if(clientfd = accept(sockfd, (struct sockaddr *)&client_addr, (socklen_t*)&addrlen) < 0)
    {
        perror("Accpet Error");
        close(sockfd);
        exit(-1);
    }

    /*Fork process*/
    if(child = fork() < 0)
    {
        perror("Fork Error");
        close(sockfd);
        exit(-1);
    }
    else if(child == 0)
    {
        int my_client = clientfd;
        close(sockfd);

        send(my_client, welcome, sizeof(welcome), 0);

        while ((res = recv(my_client, buffer1, sizeof(buffer1), 0)) > 0)
        {
            string command(buffer1);
            cout << "receive from client:" << command << ", " << res << " bytes\n";
            memset(buffer1, '\0', sizeof(buffer1));     
        }
    }

    close(clientfd);

} 

person Andy    schedule 08.11.2012    source источник
comment
Включите в вопрос соответствующие части кода, изменив его. Кодовая панель исчезнет в любое время.   -  person    schedule 08.11.2012


Ответы (1)


в вашем коде есть несколько ошибок, сначала вам нужно использовать круглые скобки вокруг назначений для child и clientfd.

строка 68 должна быть изменена на

 if((clientfd = accept(sockfd, (struct sockaddr *)&client_addr, (socklen_t*)&addrlen)) < 0)

и строка 76 должна быть

  if((child = fork()) < 0)

кроме того, вы должны return или exit() из разветвленного процесса, так как вы уже закрыли прослушивающий сокет.

поэтому добавьте exit(0); или return 0; после строки 94

Я настоятельно рекомендую вам скомпилировать код с включенными предупреждениями, чтобы выявить проблемы присваивания на ранней стадии. например, используйте флаги -Wall и -Wextra, если вы используете gcc или g++

person dwalter    schedule 08.11.2012
comment
Большое спасибо, это очень полезно для меня, я исправлю свой код и повторю попытку. СПАСИБО!!!!!!!!!! - person Andy; 08.11.2012
comment
теперь программа работает отлично, но есть еще одна проблема в том, что clientfd всегда имеет один и тот же номер, сервер не может распознать, что именно какой клиент отправляет сообщение, как я могу это исправить? Спасибо! - person Andy; 08.11.2012
comment
@ChengChung-Hao Единственное, что отличает клиентов, это их IP-адрес: порт, который вы можете получить из сокета FD через getpeername(). - person user207421; 09.11.2012