URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8965
[ Назад ]

Исходное сообщение
"accept вешается и начинает возвращать 0.0.0.0"

Отправлено vlad , 14-Дек-10 16:50 
Есть демон, слушает порт и отвечает клиентам. Он форкается и потом стоит в accept. Может нормально работать несколько суток. Потом в какой-то момент функция accept начинает возвращать 0.0.0.0 вместо адреса клиента.
Вот так открываю порт:

addr.sin_family=AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr("0.0.0.0");

bzero(&(addr.sin_zero),8);

int iServer=socket(PF_INET,SOCK_STREAM,6);
i=1;
setsockopt(iServer,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bind(iServer,(struct sockaddr*)&addr,sizeof(addr));
listen(iServer,64);

дальше в цикле:
  memset(&clientAddr,0,sizeof(clientAddr));
   int iClient = accept(iServer,(struct sockaddr*)&clientAddr,&addrlen);

    if(iClient < 0 )
    {
      printf("error in accept\r\n %s",strerror(errno));
      continue;
    }

вот, что интересно, iClient при этом ошибку не возвращает, т.е. вроде как все работает...

Может кто подскажет, что не так делаю? Почему может проработать несколько суток без вопросов, а при следующем запуске вылететь через 5 минут...

Система FreeBSD 7.2


Содержание

Сообщения в этом обсуждении
"accept вешается и начинает возвращать 0.0.0.0"
Отправлено guest , 14-Дек-10 19:58 
> Может кто подскажет, что не так делаю? Почему может проработать несколько суток
> без вопросов, а при следующем запуске вылететь через 5 минут...

Для начала я бы проверял что addrlen в accept() правильно инициализирован.

Почти ваш код:
addrlen = 0; /* Неверно. */
client = accept(server, (struct sockaddr*)&addr, &addrlen);
if (client == -1)
        err(1, "accept");
printf("accept() %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

addrlen = sizeof(addr); /* Верно. */
getpeername(client, (struct sockaddr*)&addr, &addrlen);
printf("gepeername(): %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

bash-4.1$ ./accept
Waiting for connections on 127.0.0.1 port 1234
accept() 0.0.0.0:0
gepeername(): 127.0.0.1:12861


"accept вешается и начинает возвращать 0.0.0.0"
Отправлено vlad , 14-Дек-10 21:45 
> Для начала я бы проверял что addrlen в accept() правильно инициализирован.

Спасибо за идею! я просто упустил из виду, что у меня addrlen инициализируется до входа в цикл! т.е. один корявый возврат из accept будет "вешать" разбор очереди. Т.е. у меня было:

addlen = sizeof(struct sockaddr_in);
while(true)
{
  accept(....,&addrlen);
   ....
}

Думаю проблема решена