![](/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.