LINUX.ORG.RU

быстрый возврат из ф-ции connect()


0

0

struct sockaddr_in serv_addr;

int full_server_addr(const char *ip_addr)
{
struct hostent *hp;

hp=gethostbyname(ip_addr);
if(hp==0)return -1;
bzero(&serv_addr,sizeof(serv_addr));
bcopy(hp->h_addr,&serv_addr.sin_addr,hp->h_length);
serv_addr.sin_family=hp->h_addrtype;
serv_addr.sin_port=htons((u_short)1500);
return 0;
}

void wait_connect_as_client(void)
{
int client_socket;
full_server_addr("192.168.0.20");//заполняем serv_addr
client_socket=socket(AF_INET,SOCK_STREAM,0);
while(1)
{
if(connect(client_socket,
(struct sockaddr*)&serv_addr,sizeof(serv_addr))!=-1)
{
main_loop(client_socket);//работаем пока сервер не отключится
close(client_socket);
client_socket=socket(AF_INET,SOCK_STREAM,0);
}
}
}

В функции wait_connect_as_client() пробую подключится к серверу и если успешно то работаю с ним пока не он не отключится, потом опять пытаюсь поключиться.
Проблема заключаеся в следуешем если компьтер (192.168.0.20) в сети есть то все Ок. Даже если сервер не отвечает то
connect() сразу возврашает -1, или компьтер (192.168.0.20) вообще не включен то тоже connect() сразу возврашает -1.
Но если компьтер выключить когда я к нему пытаюсь подключиться то цикл останавливается на ф-ции connect() и стоит там минут 10-15 потом продолжает работать (connect() сразу возврашает -1). Подскажите пожалуйста в чем дело, я так понимаю у сокета есть тайм-аут который для моей задачи слишком большой для меня приемлимо время ожидания не больше 5-7 секунд.


Ответ на: комментарий от cvv

Стопудовый вариант: есть такая замечательная функция select(),она имеет достаточно хитрый формат, все ее прелести и достоинства я тебе описывать не буду, но одно из ее назначений это как раз возможность задать таймаут,он задается в стуктуре(по моему,боюсь наврать,fdset),которая передается как один из параметров select'a. То есть, фактически ты можешь задать время время отклика, и никаких 10-15 минут!!! Сразу предупреждаю, прежде чем кидаться за клавиатуру ВНИМАТЕЛЬНО И ДОСКОНАЛЬНО прочти man по select'у(это очень мощная, но нетривиальная в использовании функция). Желаю удачи. Аноним.

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

Просьба не пинать (сильно) за глупый вопрос. Хочу использовать
select() чтобы не останавливаться на 10-15 минут в ф-ции connect().
вот примерно в таком виде:

client_socket=socket(AF_INET,SOCK_STREAM,0); 
while(1) 
 { 
  FD_ZERO(&rfds);
  FD_SET(client_socket,&rfds);
  tv.tv_sec=3;
  tv.tv_usec=0;
  if(select(client_socket+1,&rfds,NULL,NULL,&tv)>0)
   {
    if(connect(client_socket,
       (struct sockaddr*)&serv_addr,sizeof(serv_addr))!=-1) 
     {
      main_loop(client_socket);
      close(client_socket); 
      client_socket=socket(AF_INET,SOCK_STREAM,0); 
     }
   } 
 }
Так вот вопрос как select() определит что можно коннектиться?
ведь сокет привязывается к адресу хоста после select
(в ф-ции connect()).

CL
() автор топика
Ответ на: комментарий от CL

> Так вот вопрос как select() определит что можно коннектиться?

connect нужно делать _до_ select'а и в O_NONBLOCK mode.

послушайте, совет про select коечно где-то и правильный,
но вам проще будет просто выставить timeout, я же привел
ссылку.

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

Спасибо за совет. С timeout все работает на asplinux, но хочется иметь второй вариант т.к. до понедельника я не могу проверить будет ли это работать в ОС МСВС (мне нужно для него), предварительно там setsockopt(client_socket,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) и setsockopt(client_socket,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) не работает пишет чтото типа: протоколом не поддерживается

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