我在服务器上运行的程序与客户端上运行的另一个程序通信。他们都来回发送数据和文件。
我注意到只要有一个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秒后让它超时。
答案 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()
来读取它。