当前位置: 技术问答>linux和unix
socket中select函数求救
来源: 互联网 发布时间:2015-07-23
本文导语: 先简述一下问题: 我需要在linux下模拟windows中的异步IO模式的socket,用过WSAEventSelect和WSAEnumNetworkEvents两个函数的朋友应该对此很熟悉,我就是要模拟这两个函数,分别叫select_events, enum_events(封装在一个xsocket类中) 大体...
先简述一下问题:
我需要在linux下模拟windows中的异步IO模式的socket,用过WSAEventSelect和WSAEnumNetworkEvents两个函数的朋友应该对此很熟悉,我就是要模拟这两个函数,分别叫select_events, enum_events(封装在一个xsocket类中)
大体框架是:
使用select_events时创建一个线程,该线程负责监测socket事件并通知上层,其大致结构为:
while( 1 )
{
fd_set rset, wset, eset;
//.......
::select( pthis->m_sock+1 , &rset, &wset, &eset, NULL);
if( FD_ISSET( pthis->m_sock, &rset ) ) { }
if( FD_ISSET( pthis->m_sock, &wset ) ) { }
if( FD_ISSET( pthis->m_sock, &eset ) ) { }
}
现在的问题是:
socket创建成功后,使用select对rset和wset检测时总是有效,也就是这个循环老是在跑,郁闷啊,应该怎么办?
我需要在linux下模拟windows中的异步IO模式的socket,用过WSAEventSelect和WSAEnumNetworkEvents两个函数的朋友应该对此很熟悉,我就是要模拟这两个函数,分别叫select_events, enum_events(封装在一个xsocket类中)
大体框架是:
使用select_events时创建一个线程,该线程负责监测socket事件并通知上层,其大致结构为:
while( 1 )
{
fd_set rset, wset, eset;
//.......
::select( pthis->m_sock+1 , &rset, &wset, &eset, NULL);
if( FD_ISSET( pthis->m_sock, &rset ) ) { }
if( FD_ISSET( pthis->m_sock, &wset ) ) { }
if( FD_ISSET( pthis->m_sock, &eset ) ) { }
}
现在的问题是:
socket创建成功后,使用select对rset和wset检测时总是有效,也就是这个循环老是在跑,郁闷啊,应该怎么办?
|
if (select( pthis->m_sock+1 , &rset, &wset, &eset, NULL) > 0)
{
if( FD_ISSET( pthis->m_sock, &rset ) ) { }
if( FD_ISSET( pthis->m_sock, &wset ) ) { }
if( FD_ISSET( pthis->m_sock, &eset ) ) { }
}
If socket have nothing to send, the wset is valid.
{
if( FD_ISSET( pthis->m_sock, &rset ) ) { }
if( FD_ISSET( pthis->m_sock, &wset ) ) { }
if( FD_ISSET( pthis->m_sock, &eset ) ) { }
}
If socket have nothing to send, the wset is valid.
|
是在哪步以后select的呢? server端还是client端?
我试了下,server端在listen之后,accept之前调select是可以的,而且直到有client请求connect才会触发select的事件。
我试了下,server端在listen之后,accept之前调select是可以的,而且直到有client请求connect才会触发select的事件。
|
FD_SET( pthis->m_fds[0], &rset ); 有没有问题?
|
是不是前面初始化得不对?
先得 FD_ZERO( &rset );
然后再 FD_SET( listenfd, &rset );
select()完以后再判断。
先得 FD_ZERO( &rset );
然后再 FD_SET( listenfd, &rset );
select()完以后再判断。
|
应该是select最后一个参数的问题的吧,如果是NULL就表示要永远等待,直到其中某个描述符
准备好才中断此等待.
所以,如果你的rset和wset根本就没有准备好,那你的循环肯定是跳不出来的.
准备好才中断此等待.
所以,如果你的rset和wset根本就没有准备好,那你的循环肯定是跳不出来的.
|
fd_set必须初始化啊。
没有把他们初始化为0,FD_ZERO()
根本不能保证这个集合是空的。具体依赖于实现
没有把他们初始化为0,FD_ZERO()
根本不能保证这个集合是空的。具体依赖于实现
|
select > 0 有效 0 timeout
|
顶一下。
|
select 返回后,描述符集不会自动清零,得调用FD_ZERO