select() в LINUX
От: 1blin  
Дата: 31.01.03 14:09
Оценка:
помогите, други.
select() — ом ожидаю входящего коннетка на серверный сокет.
В man accept сказано:
In order to be notified of incoming connections on a socket, you can use select(2) or poll(2). A readable event will be delivered when a new connection is attempted and you may then call accept to get a socket for that connection.
Но в реале, когда коннектишься к этому серверу select почему-то не возвращает управление

-- вот код --
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>

#define PORTNUM 50001


int main()
{
int s_serv;
struct sockaddr_in addr_in;
fd_set rfds;

if (-1==(s_serv = socket(AF_INET,SOCK_STREAM,0))) return -1;
printf("socket\tOK\n");

addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(PORTNUM);
addr_in.sin_addr.s_addr=htonl(INADDR_ANY);

if (-1==bind (s_serv,(struct sockaddr*)&addr_in,sizeof(addr_in))) return -2;
printf("bind port %d\tOK\n",PORTNUM);

if (-1==listen(s_serv,1)) return -3;
printf("listen\tOK\n");

FD_ZERO(&rfds);
FD_SET(s_serv, &rfds);
printf (" select returns %d\n",
select(1, &rfds, NULL, NULL, NULL));
// дальше должен идти accept, но сюда управление не приходит
}
----
ЗЫ: компилилось под red hat 7.2
ЗЫ2: А под виндой (с соотв изменениями) работает!
Re: select() в LINUX
От: NavuhodonosoR Россия  
Дата: 31.01.03 14:39
Оценка:
Здравствуйте, 1blin, Вы писали:

1>select() — ом ожидаю входящего коннетка на серверный сокет. ... Но в реале, когда коннектишься к этому серверу select почему-то не возвращает управление


...
if (-1==(s_serv = socket(AF_INET,SOCK_STREAM,0))) return -1; 
    printf("socket\tOK\n"); 

addr_in.sin_family = AF_INET; 
addr_in.sin_port = htons(PORTNUM); 
addr_in.sin_addr.s_addr=htonl(INADDR_ANY); 

if (-1==bind (s_serv,(struct sockaddr*)&addr_in,sizeof(addr_in))) return -2; 
printf("bind port %d\tOK\n",PORTNUM); 

if (-1==listen(s_serv,1)) return -3; 
    printf("listen\tOK\n"); 

FD_ZERO(&rfds); 
FD_SET(s_serv, &rfds); 
printf (" select returns %d\n", select(1, &rfds, NULL, NULL, NULL)); 
// дальше должен идти accept, но сюда управление не приходит :( 
...

Сорри за предыдущий пост — заработался, не прочитал коментарий...

Ну в общем мысль почти та же — мнится мне, что сокет надо сделать неблокирующим и select() вызывать после вызова accept(). ИМХО, под линухом для серверного сокета вызвать listen() недостаточно.
Re[2]: select() в LINUX
От: 1blin  
Дата: 31.01.03 14:46
Оценка:
Здравствуйте, NavuhodonosoR, Вы писали:

NR>Цирк уехал, а клоуны остались. Ты уж извини меня за такую фразу, но ... В общем, а кто accept()-то делать будет!?!


---еще раз код--
......
if (-1==bind (s_serv,(struct sockaddr*)&addr_in,sizeof(addr_in))) return -2;
printf("bind port %d\tOK\n",PORTNUM);

if (-1==listen(s_serv,1)) return -3;
printf("listen\tOK\n");

FD_ZERO(&rfds);
FD_SET(s_serv, &rfds);
printf (" select returns %d\n",
select(1, &rfds, NULL, NULL, NULL));

// А ВОТ _ДАЛЬШЕ_ И ИДЕТ ACCEPT
bzero(&addr_w,sizeof(addr_w));
if (-1==(s_client = accept(s_serv,(struct sockaddr*)&addr_w,&addrlen))) continue;
.....
--------
Еще раз: Я селектом _определяю_ когда _придет_ входящий коннект. Так чтобы _потом_ вызвать accept и он сразу бы вернулся (не заблокировался). В выдержке из man ясно же сказано это.
Но это почему-то не происходит.
Re[2]: select() в LINUX
От: NavuhodonosoR Россия  
Дата: 31.01.03 15:27
Оценка:
NR>Ну в общем мысль почти та же — мнится мне, что сокет надо сделать неблокирующим и select() вызывать после вызова accept(). ИМХО, под линухом для серверного сокета вызвать listen() недостаточно.

Воистину "читайте маны"! Снимаю свои ответы, жаль что сам себе ноль не могу поставить. Действительно man по listen() гласит:

... a willingness to accept incoming connections and a queue limit for incoming connections are specified with listen() ...

, так что код верный. А вот почему select не разблокируется — не знаю Проверь клиента.
Re[3]: вопрос снят
От: 1blin  
Дата: 31.01.03 15:43
Оценка:
первый параметр select()-та был задан неверно. Вот и все
А в windows он игнорируется, потому, там и работало

NavuhodonosoR, спасибо за участие.

>> Проверь клиента.

клиент — telnet конечно-же обычный, что его проверять
Re[4]: вопрос снят
От: DSD Россия http://911.ru/cv
Дата: 31.01.03 19:49
Оценка:
Здравствуйте, 1blin, Вы писали:

1>первый параметр select()-та был задан неверно. Вот и все

1>А в windows он игнорируется, потому, там и работало

жаль, что я эту ветку прочитал так поздно.
у меня сразу вопрос возник, откуда уверенность, что в первый параметр нужно пихать единицу?

насколько я помню, в твоем случае этот параметр должен быть s_serv+1 (т.е. на единицу больше максимального дескриптора из проверяемых).

а s_serv у тебя врядли будет меньше тройки, потому как дескрипторы 0, 1 и 2 резервируются при старте программы под stdin, stdout и stderr соответственно.... (их конечно можно переоткрыть/переназначить, но это редко кому нужно)

З.Ы. это было так... мысли в догонку...
--
DSD
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.