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选项无效。