本文介绍了即使套接字是非阻塞的,在 Perl 上 recv 阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在守护进程中的 perl 中创建了一个这样的套接字

I have created a socket like this in perl in a daemon

IO::Socket::INET->new(LocalPort => $port,
                      Proto => 'udp',Blocking => '0') or die "socket: $@";

在 Linux 机器上

on a Linux machine

在 recv 调用期间,套接字的行为与预期的非阻塞套接字一样$sock->recv($message, 128);.

The socket behaves like non blocking socket as expected during a recv call as expected$sock->recv($message, 128);.

但是,我一直观察到,当守护程序正在运行并接收数据时重新配置 eth0 上的 VIF 时,recv 调用开始阻塞.

However, I am consistently observing that when the VIFs on eth0 are reconfigured while the daemon is running and receiving data, then the recv call starts blocking.

这是一个非常令人困惑的问题.我做了 $sock->recv($message, 128, MSG_DONTWAIT); 并且 recv 调用变得非阻塞.

This is a very perplexing issue. I did $sock->recv($message, 128, MSG_DONTWAIT); and the recv call becomes non blocking.

我用谷歌搜索过,但看不到使用 UDP 非阻塞套接字的建议方法是什么.

I have googled but could not see what is the suggested way for using UDP non blocking sockets.

推荐答案

一、字面答案:

# Portable turn-off-blocking code, stolen from POE::Wheel::SocketFactory.
sub _stop_blocking {
    my $socket_handle = shift;

    # Do it the Win32 way.
    if ($^O eq 'MSWin32') {
        my $set_it = "1";
        # 126 is FIONBIO (some docs say 0x7F << 16)
        # (0x5421 on my Linux 2.4.25 ?!)
        ioctl($socket_handle,0x80000000 | (4 << 16) | (ord('f') << 8) | 126,$set_it) or die "can't ioctl(): $!\n";
    }

    # Do it the way everyone else does.
    else {
        my $flags = fcntl($socket_handle, F_GETFL, 0) or die "can't getfl(): $!\n";
        $flags = fcntl($socket_handle, F_SETFL, $flags | O_NONBLOCK) or die "can't setfl(): $!\n";
    }
}

但是,我强烈建议您使用 AnyEvent::Handle

However, I strongly suggest you to use AnyEvent::Handle!

这篇关于即使套接字是非阻塞的,在 Perl 上 recv 阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 09:00