Netexpert FAQ 网络分析专家学习建议入口 @netexpert成员申请指南
netexpert积分规则的说明 Netis招贤纳士(2008年11月22日更新)
发新话题
打印

12.5 Winsock如何支持读超时

12.5 Winsock如何支持读超时

12.5 Winsock如何支持读超时

[url]http://www.opencjk.org/~scz/network/200610101459.txt[/url]

A: scz@nsfocus

Winsock有个独有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选项无效。
说了世上一无牵挂为何有悲喜
说了朋友相交如水为何重别离
说了少年笑看将来为何常回忆
说了青春一去无悔为何还哭泣

TOP

感谢小四哥非常精彩的tips,能不能详细的说下重叠套接字和非重叠套接字的概念。:)

[ 本帖最后由 zhouzhen 于 2006-10-12 15:37 编辑 ]

TOP

你就简单理解成是否指定了WSA_FLAG_OVERLAPPED好了。重叠操作是Win32 API的一个概念。

我给的例子里那两种创建方式都相当于指定了WSA_FLAG_OVERLAPPED。
说了世上一无牵挂为何有悲喜
说了朋友相交如水为何重别离
说了少年笑看将来为何常回忆
说了青春一去无悔为何还哭泣

TOP

发新话题
版块跳转