![](/img/trans.png)
[英]ZMQ doesn't work with the raw socket in Linux but works in Windows
[英]Socket select() works in Windows and times out in Linux
我正在将Windows网络应用程序移植到linux,并且在linux上选择调用时遇到超时问题。 以下函数将阻止整个超时值,并在我用包嗅探器检查客户端已发送数据时返回。
int recvTimeOutTCP( SOCKET socket, long sec, long usec )
{
struct timeval timeout;
fd_set fds;.
timeout.tv_sec = sec;
timeout.tv_usec = usec;
FD_ZERO( &fds );
FD_SET( socket, &fds );
// Possible return values:
// -1: error occurred
// 0: timed out
// > 0: data ready to be read
cerr << "Waiting on fd " << socket << endl;
return select(1, &fds, 0, 0, &timeout);
}
我认为select()
的第一个参数应该是socket+1
。
您确实应该使用其他名称,因为socket
也用于其他用途。 通常使用sock
。
从选择的手册页中:
int select(int nfds,
fd_set* restrict readfds,
fd_set* restrict writefds,
fd_set* restrict errorfds,
struct timeval* restrict timeout);
在每个集合中检查第一个nfds描述符; 也就是说,检查描述符集中从0到nfds-1的描述符。
因此,要选择的第一个参数应该是socket + 1。
return select(socket + 1, &fds, 0, 0, &timeout);
Windows上的select
忽略第一个参数。 从MSDN:
C++
int select(
__in int nfds,
__inout fd_set *readfds,
__inout fd_set *writefds,
__inout fd_set *exceptfds,
__in const struct timeval *timeout
);
Parameters
nfds [in]
Ignored. The nfds parameter is included only for
compatibility with Berkeley sockets.
...
问题是Linux中的fd_set是一个位数组(起初它只是一个int,但随后您只能观看进程的前16个io)。 在Windows中,fd_set是一个套接字数组,其长度在前面(这就是为什么Windows不需要知道要监视多少位的原因)。
poll()函数接受一系列记录以在Linux上观看,并且具有其他优点,这使其比select()更好。
int recvTimeOutTCP( SOCKET socket, long msec )
{
int iret ;
struct polldf sockpoll ;
sockpoll.fd= socket ;
sockpoll.events= POLLIN ;
return poll(& sockpoll, 1, msec) ;
}
要选择的第一个参数(...)是要在集合中检查的文件描述符的数量。 您的呼叫告诉它仅查看文件描述符0,这几乎可以肯定不是套接字设置的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.