WinSoc32 API и select(..)?
От: flush  
Дата: 09.03.02 12:37
Оценка:
Здравствуйте!

Мне необходимо использовать WinSock32 API для обмена
небольшими сообщениями по сети. Но я столкнулся со следующей
проблемой:
Перед чтением из неблокирующего socketa я первоначально вызываю
select( ) как показано ниже.

SOCKET other_node;

...

for( ;; )
{
fd_set read_fds;
FD_ZERO( &read_fds ); FD_SET( otherNode, &read_fds );
timeval time_val; time_val.tv_sec = 1; time_val.tv_usec = 0;
int sret = select( otherNode+1, &read_fds, 0, 0, &time_val );
if( sret == SOCKET_ERROR )
throw error_read();
else
if( sret )
break;
else
continue;
}

Так вот если удаленная машина нормально закрывает соединение или
я сам завершаю процесс на ней, то выход из цикла происходит успешно.
Но если я вынимаю сетевой кабель, то цикл не прекращается никогда,
что вызывает некоторые неудобства .
Хотя в MSDN написано что select возвращает значение больше нуля
если Connection has been closed/reset/terminated.

Помогите пожалуйста разобраться с проблемой.
Re: WinSoc32 API и select(..)?
От: SergH Россия  
Дата: 09.03.02 22:20
Оценка:
Здравствуйте flush, Вы писали:

F> Здравствуйте!


F> Мне необходимо использовать WinSock32 API для обмена

F>небольшими сообщениями по сети. Но я столкнулся со следующей
F>проблемой:
F> Перед чтением из неблокирующего socketa я первоначально вызываю
F>select( ) как показано ниже.

F> SOCKET other_node;


F> ...


F> for( ;; )

F> {
F> fd_set read_fds;
F> FD_ZERO( &read_fds ); FD_SET( otherNode, &read_fds );
F> timeval time_val; time_val.tv_sec = 1; time_val.tv_usec = 0;
F> int sret = select( otherNode+1, &read_fds, 0, 0, &time_val );
F> if( sret == SOCKET_ERROR )
F> throw error_read();
F> else
F> if( sret )
F> break;
F> else
F> continue;
F> }
F>
F> Так вот если удаленная машина нормально закрывает соединение или
F>я сам завершаю процесс на ней, то выход из цикла происходит успешно.
F>Но если я вынимаю сетевой кабель, то цикл не прекращается никогда,
F>что вызывает некоторые неудобства .
F>Хотя в MSDN написано что select возвращает значение больше нуля
F>если Connection has been closed/reset/terminated.

F> Помогите пожалуйста разобраться с проблемой.



Примерно полгода назад я писал проект на API с использованием WinSock'а. Я использовал WSAEventSelect и таких проблем не было (специально проверял).
Делай что должно, и будь что будет
Re: WinSoc32 API и select(..)?
От: Sashko Россия http://www.dc.baika.ru/
Дата: 10.03.02 07:02
Оценка:
Здравствуйте flush, Вы писали:

F>    fd_set read_fds;
F>    FD_ZERO( &read_fds ); FD_SET( otherNode, &read_fds );
F>    timeval time_val; time_val.tv_sec = 1; time_val.tv_usec = 0;
F>    int sret = select( otherNode+1, &read_fds, 0, 0, &time_val );


F>

F> Так вот если удаленная машина нормально закрывает соединение или
F>я сам завершаю процесс на ней, то выход из цикла происходит успешно.
F>Но если я вынимаю сетевой кабель, то цикл не прекращается никогда,
F>что вызывает некоторые неудобства .
F>Хотя в MSDN написано что select возвращает значение больше нуля
F>если Connection has been closed/reset/terminated.

F> Помогите пожалуйста разобраться с проблемой.



int select(
  int nfds,                           
  fd_set FAR *readfds,               
  fd_set FAR *writefds,              
  fd_set FAR *exceptfds,             
  const struct timeval FAR *timeout  
);


exceptfds 
    [in, out] Optional pointer to a set of sockets to be checked for errors.


Создай еще оидн FD set, и используй его в качестве exceptfds параметра.

fd_set read_fds;
fd_set except_fds;
timeval time_val = { 1, 0 };

FD_ZERO(&read_fds);
FD_ZERO(&except_fds);

for (;;) 
{ 
    FD_SET(otherNode, &read_fds);
    FD_SET(otherNode, &except_fds);

    if (SOCKET_ERROR == select(0, &read_fds, 0, &except_fds, &time_val))
        throw error_read();

    if (FD_ISSET(otherNode, &read_fds))
    {
        // need read
    }
    if (FD_ISSET(otherNode, &except_fds))
    {
        // some error
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.