Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 套接字选择()在Windows中工作,在Linux中超时_C++_Linux_Sockets_Select - Fatal编程技术网

C++ 套接字选择()在Windows中工作,在Linux中超时

C++ 套接字选择()在Windows中工作,在Linux中超时,c++,linux,sockets,select,C++,Linux,Sockets,Select,我正在将一个windows网络应用程序移植到linux,并且在linux上遇到了select调用超时问题。当我使用数据包嗅探器检查客户机是否已经发送了数据时,以下函数会阻塞整个超时值并返回 int recvTimeOutTCP( SOCKET socket, long sec, long usec ) { struct timeval timeout; fd_set fds;. timeout.tv_sec = sec; timeout.tv_usec = usec; FD

我正在将一个windows网络应用程序移植到linux,并且在linux上遇到了select调用超时问题。当我使用数据包嗅探器检查客户机是否已经发送了数据时,以下函数会阻塞整个超时值并返回

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);
}
int recvTimeOutTCP(套接字,长秒,长usec)
{
结构timeval超时;
fd_设置fds;。
timeout.tv_sec=秒;
timeout.tv_usec=usec;
FD_零(&fds);
FD_装置(插座和fds);
//可能的返回值:
//-1:发生错误
//0:超时
//>0:准备好读取的数据

cerr我认为
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);

(…)的第一个参数是要在集合中签入的文件描述符的数目。您的调用告诉它只查看文件描述符0,这几乎肯定不是socket设置的值。

在Windows上选择将忽略第一个参数。从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_集是一个位数组(最初它只是一个int,但之后您只能查看进程的前16个io)。在windows中,fd_集是一个插槽数组,前面有一个长度(这就是为什么windows不需要知道要查看多少位)

poll()函数可以在linux上查看一组记录,并具有其他优点,因此它比select()更好


@jamessan啊,是的,我的意思是;)对。
int-select(int-nfds,fd_-set*readfds,fd_-set*writefds,fd_-set*exceptfds,struct-timeval*timeout);
其中nfds是三个集合中编号最高的文件描述符,加上1。
Windows中的实现忽略了第一个参数!酷!无需暗示-这在Microsoft的
select()
文档中有明确说明:感谢您提供的信息,这个poll()函数是否可能跨平台?嗯,在Linux上,您真的想使用epoll,最好是在边缘触发模式下。
int recvTimeOutTCP( SOCKET socket, long msec )
{
    int iret ;
    struct polldf   sockpoll ;

    sockpoll.fd= socket ;
    sockpoll.events= POLLIN ;

    return poll(& sockpoll, 1, msec) ;
}