📄 程嶏清单 17-10.txt
字号:
程序清单17-10:disconnect.pl
sub _rcv {
my ($conn, $rcv_now) = @_;
my ($msg, $offset, $bytes_to_read, $bytes_read);
my $sock = $conn->{sock};
return unless defined($sock);
if (exists $conn->{msg}) {
$msg = $conn->{msg};
delete $conn->{'msg'};
$offset = length($msg) - 1;
$bytes_to_read = $conn->{bytes_to_read};
} else {
# 这是典型的情况
$msg = "";
$offset = 0 ;
$bytes_to_read = 0 ; # Will get set soon
}
# 以阻塞模式来读取消息的长度信息,这里假设在读取四个字节信息的时间内时不
# 会阻塞的
if (!$bytes_to_read) { # 获取新的长度信息
my $buf;
$conn->set_blocking();
$bytes_read = sysread($sock, $buf, 4);
if ($! || ($bytes_read != 4)) {
goto FINISH;
}
$bytes_to_read = unpack ('N', $buf);
}
$conn->set_non_blocking() unless $rcv_now;
while ($bytes_to_read) {
$bytes_read = sysread ($sock, $msg, $bytes_to_read, $offset);
if (defined ($bytes_read)) {
if ($bytes_read == 0) {
last;
}
$bytes_to_read -= $bytes_read;
$offset += $bytes_read;
} else {
if (_err_will_block($!)) {
# 只能以非阻塞模式运行到这里
$conn->{msg} = $msg;
$conn->{bytes_to_read} = $bytes_to_read;
return ; # 返回事件循环,当套接字再次可以读时,_rcv将会被调用
} else {
last;
}
}
}
# 消息成功读取
FINISH:
if (length($msg) == 0) {
$conn->disconnect();
}
if ($rcv_now) {
return ($msg, $!);
} else {
&{$conn->{rcvd_notification_proc}}($conn, $msg, $!);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -