簡體   English   中英

套接字select()在Windows中工作,在Linux中超時

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM