如何在c ++中超时recv()函数?

时间:2011-07-13 22:05:01

标签: c++ sockets tcp timeout tcplistener

我在服务器上运行的程序与客户端上运行的另一个程序通信。他们都来回发送数据和文件。

我注意到只要有一个socHandler.read()(读取套接字上的数据的函数),它就会等待数据到达。

这就是函数的样子。

int CSocHandler::read(char * inBuffer, INT64 iBytesToRead){

    bool blReadMore=false;
    int retVal = 0;

    int iOutputPointer = 0;


    do{
        blReadMore = false;
        if (iStartOfBuffer == iEndOfBuffer) {   //Buffer empty
            if (blClosed ) {
                return -1;
            }
            iStartOfBuffer = 0;
            iEndOfBuffer = 0;
            size_t bufferRemaining = BUFFER_SIZE-iEndOfBuffer;
                        int bytesRecvd = recv( sock, &buffer[iEndOfBuffer], (int)iBytesToRead<bufferRemaining?iBytesToRead:bufferRemaining), 0 );   
            if ( bytesRecvd <= 0) {
                close();
                Yield();
                return retVal;
            }
        }
    } while(blReadMore);

    return retVal;
  }

变量sock是一个SOCKET类型,是一个在别处定义的全局变量。如何设置选项或仅对此函数调用使此recv()调用非阻塞而不影响任何其他函数?

我相信这是等待数据的地方,我希望在X秒后让它超时。

2 个答案:

答案 0 :(得分:3)

select(2)之前的套接字上使用recv

使用Perl语法,它看起来像

sub read_with_timeout {
   my ($sock, $bytes_to_read, $timeout) = @_;

   my $sel = IO::Select->new($sock);
   my $end_time = Time::HiRes::time() + $timeout;

   my $buf = '';
   while ($bytes_to_read) {
      $timeout >= 0 && () = $sel->can_read($timeout);
         or die("Timeout");

      my $rv = sysread($sock, $buf, $bytes_to_read, length($buf));
      die "read: $!" if !defined($rv);
      die "Premature eof" if !$rv;

      $bytes_to_read -= $rv;

      $timeout = $end_time - Time::HiRes::time();
   }

   return $buf;
}

can_read是对select(2)的调用。

答案 1 :(得分:3)

调用select()以查询套接字是否有任何待处理数据,然后再调用recv()来读取它。