用select设置超时时间

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
      
SOCKET sListen = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
SOCKADDR_IN sin;
sin.sin_family
= AF_INET;
sin.sin_addr.S_un.S_addr
= INADDR_ANY;
sin.sin_port
= htons(CDownCfg::GetUDPClientPort());

::bind(sListen,(SOCKADDR
* ) & sin, sizeof (sin));

int iMode = 1 ; // 0:阻塞
ioctlsocket(sListen,FIONBIO,(u_long FAR * ) & iMode); // 非阻塞设置


SOCKADDR_IN addrRemote;
int nRemote = sizeof (SOCKADDR_IN);

//
// Select
fd_set fdSocket;
FD_ZERO(
& fdSocket);
FD_SET(sListen,
& fdSocket);
//
// 超时限制为5秒
struct timeval timeout;
timeout.tv_sec
= 5 ;
timeout.tv_usec
= 0 ;

while (TRUE)
{
int nSele = select( 0 , & fdSocket,NULL,NULL, & timeout);
char recvbuf[ 256 ];
int nRet = 0 ;

if (nSele > 0 )
nRet
= ::recvfrom(sListen,recvbuf, 256 , 0 ,(SOCKADDR * ) & addrRemote, & nRemote);

else
break ;
}

这是一段UDP服务器的代码,场景是在你广播之后收听应答。如果超时5秒内没有出现应答,则不再收听,认为所有应答已经接收完毕。注意其中select的用法。

 

《Windows网络通信与程序设计》一书中很早就有提到过这个函数的常规用法,由此观之,很多函数的深入理解不在于说按照常规你可以怎么走,而是说,这个函数可以给你提供怎样的可能性。而仔细深究下去,有一个疑问,为什么可以先select再去recvfrom。select是返回所有发生网络事件的套接字的总和,那么我现在根本没有去recvfrom,为什么就发生了网络事件呢?也许这就是UDP的特殊之处所在。目前这个问题只能留待以后去理解。

 

 

posted on 2010-05-17 16:52 Duckhyx 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/yellowswan/archive/2010/05/17/1737489.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值