LINUX.ORG.RU

Странные баги в маленьком примере на C


0

0

Hi All!

Вот программка (UDP-сервер).

main(int argc, char** argv)
{
   struct sockaddr_in server;
   char buf[1024];
   int sd;
   int rc;
   unsigned short port_num = 9999;

   // Server params
   server.sin_family = AF_INET;
   server.sin_addr.s_addr = htonl(INADDR_ANY);
   server.sin_port = htons(port_num);

   // New socket
   sd = socket (AF_INET,SOCK_DGRAM,0);
   assert(sd != -1);

   // Bind socket to server port
   rc = bind (sd, (struct sockaddr *) &server, sizeof(server));
   assert(rc != -1);

   struct sockaddr_in serv;
   socklen_t serv_len;

   // Main loop
   for(;;)
     {
       rc = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&serv, &serv_len);
       buf[rc]= (char) NULL;
       printf("addr = '%u' len = '%u' buf = '%s'\n",serv.sin_addr.s_addr, serv_len, buf);
     }
}


После её запуска я вижу:
addr = '16777343' len = '16' buf = 'HELLO'
Всё здорово! (16777343 - это 127.0.0.1 в network byte order).

Меняем программку слегка:
main(int argc, char** argv)
{
   struct sockaddr_in server;
   char buf[1024];
   int sd;
   int rc;
   unsigned short port_num = 9999;

   // Server params
   server.sin_family = AF_INET;
   server.sin_addr.s_addr = htonl(INADDR_ANY);
   server.sin_port = htons(port_num);

   // New socket
   sd = socket (AF_INET,SOCK_DGRAM,0);
   assert(sd != -1);

   // Bind socket to server port
   rc = bind (sd, (struct sockaddr *) &server, sizeof(server));
   assert(rc != -1);

   // Main loop
   for(;;)
     {
       struct sockaddr_in serv;
       socklen_t serv_len;

       rc = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&serv, &serv_len);
       buf[rc]= (char) NULL;
       printf("addr = '%u' len = '%u' buf = '%s'\n",serv.sin_addr.s_addr, serv_len, buf);
     }
}

После её запуска я опять вижу:
addr = '16777343' len = '16' buf = 'HELLO'
Опять всё правильно!

Проблема:
Запускал я это в Gentoo. Всё работало.

А вот затем попробовал с KNOPPIX 5.0 LIVE-DVD.
Скомпилил прогу номер 1 - всё OK!

Затем прогу номер 2 - в поле адреса и длины выводится какая-то 
ху@ня!!!
Если конкретно - 3084534624/32197988328.

В чём разница??? Ну убрал/добавил переменные в тело цикла. И что?
Поведение стабильное!!! Память вроде не течёт (негде).
Что с KNOPPIX'ом???
anonymous

из мана:

Если параметр from не равен NULL, а сокет не является ориентированным на соединения, то адрес отправителя в сообщении не заполняется. Аргумент fromlen передается по ссылке, в начале инициализируется размером буфера, связанного с from, а при возврате из функции содержит действительный размер адреса.

судя по коду вы собираете это g++, ну или gcc -std=c99 или вроде того. попробуйте в цикле устанавливать всё в 0.

legk
()

Ты бы #include'ы не выкидывал.

У меня (SuSE) они обе выводят, как ты выразился, "ху@ню". Дело в том, что recvfrom не срабатывает с errno = Invalid argument. А прикол в том, что serv_len надо инициализировать значением sizeof(serv)

anonymous
()

обнуляй структуры перед использованием

man memset

theserg ★★★
()
Ответ на: комментарий от anonymous

так что замени

socklen_t serv_len;

на

socklen_t serv_len = sizeof(serv);

и все заработает

anonymous
()
Ответ на: комментарий от legk

// Main loop
   for(;;)
     {
       struct sockaddr_in serv;
       socklen_t serv_len;

       serv_len = sizeof(serv);
       rc = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&serv, &serv_len);
       buf[rc]= (char) NULL;
       printf("addr = '%u' len = '%u' buf = '%s'\n",serv.sin_addr.s_addr, serv_len, buf);
     }

legk
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.