📄 程嶏清单 17-8.txt
字号:
程序清单17-8:_send.pl
sub _send {
my ($conn, $flush) = @_;
my $sock = $conn->{sock}; # conn为连接对象,这是哈希表的引用语句
return unless defined($sock);
my ($rq) = $conn->{queue}; #指向消息队列的引用.
# 如果设置了$flush,则将套接字设置为阻塞模式,于是将所有队列中的消息发送出去,只有
# 在发生错误时返回;如果将 $flush设置为0,那么套接字将被设置为非阻塞模式,这样只有# 在每个消息发送后或者是有可能在发送消息当中阻塞时,才返回事件循环
$flush ? $conn->set_blocking() : $conn->set_non_blocking();
my $offset = (exists $conn->{send_offset}) ? $conn->{send_offset} : 0;
while (@$rq) {
my $msg = $rq->[0];
my $bytes_to_write = length($msg) - $offset;
my $bytes_written = 0;
while ($bytes_to_write) {
$bytes_written = syswrite ($sock, $msg,
$bytes_to_write, $offset);
if (!defined($bytes_written)) {
if (_err_will_block($!)) {
# 应当只发生在延迟模式,记下已经发送的数量
$conn->{send_offset} = $offset;
# 由于事件处理程序应当已经进行了设置,因此最终要进行回调并恢复发送
return 1;
} else { # Uh, oh
$conn->handle_send_err($!);
return 0; # fail. Message remains in queue ..
}
}
$offset += $bytes_written;
$bytes_to_write -= $bytes_written;
}
delete $conn->{send_offset};
$offset = 0;
shift @$rq;
last unless $flush; # Go back to select and wait
# for it to fire again.
}
# 如果队列中的消息没有发送完,就回调次函数
if (@$rq) {
set_event_handler ($sock, "write" => sub {$conn->_send(0)});
} else {
set_event_handler ($sock, "write" => undef);
}
1; # 类似于return 1;语句,表示此函数执行成功
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -