Здравствуйте!
Мне необходимо использовать 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.
Помогите пожалуйста разобраться с проблемой.
Здравствуйте 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 и таких проблем не было (специально проверял).
Здравствуйте 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
}
}