Socket中如何设置连接超时

Socket中如何设置连接超时
(antghazi发表于2003-3-16 9:28:38)

  设置connect的超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案。偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使那些想避免在套接字调用过程中被锁定的应用程序,采取一种有序的方式,同时对多个套接字进行管理"(《Windows网络编程技术》原话)。使用方法与解释请见《Windows网络编程技术》。
  在使用此函数前,需先将socket设置为非锁定模式,这样,在connect时,才会立马跳过,同时,通常也会产生一个WSAEWOULDBLOCK错误,这个错误没关系。再执行select则是真正的超时。

None.gif WSADATA wsd;
None.gifSOCKET cClient;
None.gif
int  ret;
None.gif
struct  sockaddr_in server;
None.gifhostent 
* host = NULL;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
if (WSAStartup(MAKEWORD( 2 , 0 ), & wsd)) dot.gif {return 0;}
None.gifcClient
= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
ExpandedBlockStart.gifContractedBlock.gif
if (cClient == INVALID_SOCKET) dot.gif {return 0;}
None.gif
// set Recv and Send time out
None.gif
int  TimeOut = 6000 // 设置发送超时6秒
ExpandedBlockStart.gifContractedBlock.gif
if (::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,( char   * ) & TimeOut, sizeof (TimeOut)) == SOCKET_ERROR) dot.gif {
InBlock.gif
return 0;
ExpandedBlockEnd.gif}

None.gifTimeOut
= 6000 ; // 设置接收超时6秒
ExpandedBlockStart.gifContractedBlock.gif
if (::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,( char   * ) & TimeOut, sizeof (TimeOut)) == SOCKET_ERROR) dot.gif {
InBlock.gif
return 0;
ExpandedBlockEnd.gif}

None.gif
// 设置非阻塞方式连接
None.gif
unsigned  long  ul  =   1 ;
None.gifret 
=  ioctlsocket(cClient, FIONBIO, (unsigned  long * ) & ul);
None.gif
if (ret == SOCKET_ERROR) return   0 ;
None.gif
None.gif
// 连接
None.gif
server.sin_family  =  AF_INET;
None.gifserver.sin_port 
=  htons( 25 );
None.gifserver.sin_addr .s_addr 
=  inet_addr((LPCSTR)pSmtp);
ExpandedBlockStart.gifContractedBlock.gif
if (server.sin_addr.s_addr  ==  INADDR_NONE) dot.gif {return 0;}
None.gif
None.gifconnect(cClient,(
const   struct  sockaddr  * ) & server, sizeof (server));
None.gif
None.gif
// select 模型,即设置超时
None.gif
struct  timeval timeout ;
None.giffd_set r;
None.gif
None.gifFD_ZERO(
& r);
None.gifFD_SET(cClient, 
& r);
None.giftimeout.tv_sec 
=   15 // 连接超时15秒
None.gif
timeout.tv_usec  = 0 ;
None.gifret 
=  select( 0 0 & r,  0 & timeout);
None.gif
if  ( ret  <=   0  )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif::closesocket(cClient);
InBlock.gif
return 0;
ExpandedBlockEnd.gif}

None.gif
// 一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
None.gif
unsigned  long  ul1 =   0  ;
None.gifret 
=  ioctlsocket(cClient, FIONBIO, (unsigned  long * ) & ul1);
ExpandedBlockStart.gifContractedBlock.gif
if (ret == SOCKET_ERROR) dot.gif {
InBlock.gif::closesocket (cClient);
InBlock.gif
return 0;
ExpandedBlockEnd.gif}

None.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值