以下面的代码片段为例,创建套接字,监听和接受新套接字工作正常。非阻塞模式也在工作,但是pselect(甚至用select替换)不能识别FDset上准备好的任何IO请求。所以返回值始终为0(超时)。
我想知道在进入pselect()之前是否需要进一步设置其他内容以便识别IO活动。
.....
// Create the socket
*m_pSockFD = socket(AF_INET, SOCK_STREAM, 0);
if( *this->m_pSockFD == -1 ){
throw ....
}
// Set the socket address information
m_pSockAddr->sin_family = AF_INET;
m_pSockAddr->sin_port = htons( 6001 );
m_pSockAddr->sin_addr.s_addr = INADDR_ANY;
if( bind(*m_pSockFD, (struct sockaddr *) m_pSockAddr, sizeof(*m_pSockAddr) ) != 0 ){
.....
}
// Listen on this socket using a block queue of 5 - default Block Size
if( listen( *m_pSockFD, 5) != 0 )
........
// change function control to non blocking file descritor for I/O operations
long fcntlArg;
if( (fcntlArg = fcntl( *m_pSockFD, F_GETFL, NULL ) ) < 0 ){
...........
}
fcntlArg |= O_NONBLOCK;
if( fcntl( *m_pSockFD, F_SETFL, fcntlArg ) <0 ){
...........
}
//.........
int newFD = -1;
socklen_t salen = sizeof(*m_pSockAddr);
// loop selecting for a I/O operation ready on the file descriptor then go into accept mode
struct timespec timeOut;
timeOut.tv_sec = 1;
timeOut.tv_nsec = 0;
fd_set fdset;
FD_SET( *this->m_pSockFD, &fdset );
while( !m_bShutDownFinished ){
// TODO pselect is not registering the activity on the socket
if( pselect( *this->m_pSockFD, &fdset, NULL , NULL , &timeOut, NULL ) > 0 ){
cout << "hello client" << endl;
break;
}
// re-initialize the time struct
timeOut.tv_sec = 1;
timeOut.tv_nsec = 0;
}
// application is shutting down do not try to accept a new socket
if( m_bShutDownFinished ) return -1;
newFD = accept(*m_pSockFD, (struct sockaddr *) m_pSockAddr, &salen);
if( newFD > -1 ){
................
}
return newFD;
答案 0 :(得分:4)
在每次调用select()
之前,您必须重新初始化fdset参数。
readfds
,writefds
和exceptfds
中的每一个都是输入/输出参数。返回时,它们被修改为只有fds,它们分别是可读,可写或具有某种特殊条件的。
for (;;) {
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
/* code to set up timeout omitted */
n = select(sock + 1, &rfds, 0, 0, &timeout);
/* check n, and if sock is present in rfds */
}
您编写代码的方式,只有在第一次调用pselect()
期间到达时才会检测到传入连接。另外,鉴于您未使用sigmask
的{{1}}参数,您也可以致电pselect()
。
答案 1 :(得分:0)
pselect的第一个参数应该是*this->m_pSockFD + 1
,不应该吗?