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).
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论