开发者

How do I timeout a recv() function in c++?

开发者 https://www.devze.com 2023-03-20 07:50 出处:网络
I have a program running on a server communicating with another program running on the client. They both sen开发者_开发知识库d data and files back and forth.

I have a program running on a server communicating with another program running on the client. They both sen开发者_开发知识库d data and files back and forth.

I notice that whenever there is a socHandler.read() (function to read data coming in on socket), it gets stuck waiting for data to arrive.

This is what the function looks like.

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;
  }

The variable sock is a type SOCKET and is a global variable defined elsewhere. How can I set the options or make this recv() call non-blocking only for this function call and no affect any other function?

I believe this is where it gets stuck waiting for data, and I want to make it timeout after X seconds.


Call select() to query if the socket has any pending data before then calling recv() to read it.


Use select(2) on the socket before the recv.

Using Perl syntax, it would look like

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 is a call to select(2).

0

精彩评论

暂无评论...
验证码 换一张
取 消