12.5 Winsock如何支持读超时
https://scz.617.cn/network/200610101459.txt
A: scz@nsfocus
Winsock有个Windows独有的SO_RCVTIMEO选项:
int i = timeout;
if ( SOCKET_ERROR == setsockopt ( s, SOL_SOCKET, SO_RCVTIMEO, ( char * )&i, sizeof( i ) ) ) { ... ... }
如果碰上不支持SO_RCVTIMEO选项的情形,还可以利用select()实现读超时:
static int recv_with_timeout ( SOCKET s, char FAR *buf, int len, int flags, unsigned int timeout ) { int error; fd_set rset, eset; struct timeval tv; int ret = SOCKET_ERROR;
FD_ZERO( &rset );
FD_ZERO( &eset );
FD_SET( s, &rset );
FD_SET( s, &eset );
tv.tv_sec = timeout;
tv.tv_usec = 0;
error = select( 0, &rset, NULL, &eset, timeout ? &tv : NULL );
if ( SOCKET_ERROR == error )
{
}
else if ( 0 == error )
{
}
else if ( FD_ISSET( s, &rset ) )
{
ret = recv( s, buf, len, flags );
}
else
{
}
return( ret );
} / end of recv_with_timeout /
Q: 系统支持SO_RCVTIMEO选项,但实测下来读超时没有生效。
A: scz@nsfocus 2006-10-10 14:44
检查一下如何创建套接字的,要确保在重叠套接字上使用SO_RCVTIMEO选项:
SOCKET s;
if 1
s = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
else
s = WSASocket ( PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED );
endif
if ( INVALID_SOCKET == s ) { ... ... }
非重叠套接字(non-overlapped socket)上SO_RCVTIMEO选项无效。