您的位置:首页 > 其它

Socket中如何设置连接超时(转)

2011-06-28 10:34 525 查看
http://tangfeng.iteye.com/blog/795497

Socket中可以使用select设置连接超时,需要先将socket设置为非锁定模式,这样,在connect时,才会立马跳过,同时,通常也会产生一个WSAEWOULDBLOCK错误,这个错误没关系。再执行select则是真正的超时。

C++代码



WSADATA wsd;

SOCKET cClient;

int ret;

struct sockaddr_in server;

hostent *host = NULL;

if (WSAStartup(MAKEWORD(2,0), &wsd))

{

return 0;

}

cClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (cClient == INVALID_SOCKET)

{

return 0;

}

// set Recv and Send time out

DWORD TimeOut = 6000; // 设置发送超时6秒

if (::setsockopt(cClient, SOL_SOCKET, SO_SNDTIMEO, (char *)&TimeOut, sizeof(TimeOut)) == SOCKET_ERROR)

{

return 0;

}

TimeOut = 6000; // 设置接收超时6秒

if (::setsockopt(cClient, SOL_SOCKET, SO_RCVTIMEO, (char *)&TimeOut, sizeof(TimeOut)) == SOCKET_ERROR)

{

return 0;

}

// 设置非阻塞方式连接

unsigned long ul = 1;

ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);

if (ret == SOCKET_ERROR)

return 0;

// 连接

server.sin_family = AF_INET;

server.sin_port = htons(25);

server.sin_addr.s_addr = inet_addr((LPCSTR)pSmtp);

if (server.sin_addr.s_addr == INADDR_NONE)

return 0;

connect(cClient, (const struct sockaddr*)&server, sizeof(server));

// select 模型,即设置超时

struct timeval timeout ;

fd_set r;

FD_ZERO(&r);

FD_SET(cClient, &r);

timeout.tv_sec = 15; // 连接超时15秒

timeout.tv_usec = 0;

ret = select(0, 0, &r, 0, &timeout);

if (ret <= 0)

{

::closesocket(cClient);

return 0;

}

// 一般非锁定模式套接字比较难控制,可以根据实际情况考虑再设回阻塞模式

unsigned long ul1 = 0;

ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);

if (ret == SOCKET_ERROR)

{

::closesocket(cClient);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: