用select设置超时时间
代码
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