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

发布于 2024-11-19 22:59:24 字数 1075 浏览 2 评论 0原文

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

我注意到,每当有 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 秒后超时。

I have a program running on a server communicating with another program running on the client. They both send 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兔姬 2024-11-26 22:59:24

调用 select() 查询套接字是否有任何未决数据,然后调用 recv() 读取数据。

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

孤独患者 2024-11-26 22:59:24

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

使用 Perl 语法,can_read 看起来像是

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

select(2) 的调用。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文