Почему функция привязки возвращает -1 (сбой привязки)?

Я пытаюсь привязать сокет к IP-адресу и порту, на котором он будет прослушивать соединения. Вот мой соответствующий код (комментарии w и отладочные операторы печати)

#define PORTNUM 2345
int main(int argc, char *argv[])
{
        // socket info about client connecting to server
        struct sockaddr_in dest;
        //socket info about server 
        struct sockaddr_in serv; 
        //socket used to listen for incoming connections 
        int mysocket;            
        //zero the struct before filling the fields 
        memset(&serv, 0, sizeof(serv)); 
        //set connection type to tcp/ip           
        serv.sin_family = AF_INET; 
        //set should be be bound to ip of the machine on which process currently executing               
          serv.sin_addr.s_addr = htonl(INADDR_ANY); 
         //set server port number
         serv.sin_port = htons(PORTNUM);
          //create the socket to liste for connection 
           mysocket = socket(AF_INET, SOCK_STREAM, 0);
        printf("value of socket:%d\n", mysocket);
         // bind serv information to mysocket 
      int v=  bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
      printf("value of bind: %d\n", v);

       return 1;   
}

Вот мои операторы печати отладки, когда я запускаю свой код

Value of socket: 3
Value of bind: -1

Когда я читаю документацию http://linux.die.net/man/2/bind, я видел, что функция привязки вернет -1 для ошибки (сбой привязки). Основываясь на моем коде, кто-нибудь знает, почему эта операция не удалась? Я просмотрел свой код и думаю, что у меня все настроено (все комментарии). Я даже убедился, что номер порта, который я использовал, находится в диапазоне, назначенном приложениям (1024 - 49151). На основе http://man7.org/linux/man-pages/man2/socket.2.html, я знаю, что сокет был успешно создан (возвращаемое значение 3, а не -1)


person committedandroider    schedule 20.11.2014    source источник
comment
Вызовите perror("bind");, чтобы распечатать актуальную ошибку. Видите в этой документации, которую вы связали, все ошибки, которые может вернуть привязка? Они сохраняются в глобальной переменной с именем errno, к которой вы можете получить прямой доступ, включив errno.h. perror() — вспомогательная функция, объявленная в stdio.h.   -  person indiv    schedule 21.11.2014
comment
Где я могу вызвать ошибку? Сразу после звонка на привязку?   -  person committedandroider    schedule 21.11.2014
comment
Да, прежде чем вы сделаете что-нибудь еще. Вы хотите, чтобы ваш код был похож на int v = bind(...); if( v < 0 ) { perror("bind"); }   -  person indiv    schedule 21.11.2014


Ответы (1)


./err 
value of socket:3
value of bind: 0

Итак, это работает. В коде нет ничего плохого. Скорее всего, порт уже используется другой программой, или более ранняя версия вашей программы находится в состоянии очистки, из-за чего порт занят. Для подтверждения используйте perror() сразу после вызова bind. Также найдите параметр сокета SO_REUSEADDR, чтобы разрешить привязку к порту, находящемуся в состоянии очистки.

person hdante    schedule 20.11.2014
comment
Да, теперь странно, что написано bind:Success. Должно быть, более ранняя версия программы находилась в состоянии очистки. Как долго вам обычно приходится ждать, пока эта более ранняя версия выйдет из состояния очистки? - person committedandroider; 21.11.2014
comment
Я запустил его снова, и он сказал: «Привязка: адрес используется». Есть ли период времени, который вам нужно подождать, прежде чем привязка снова заработает? - person committedandroider; 21.11.2014
comment
Это может быть 60 секунд или больше. Вам обязательно нужно включить SO_REUSEADDR, чтобы разрешить быструю привязку. - person hdante; 21.11.2014