4

私はデーモンのperlでこのようなソケットを作成しました

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

Linuxマシンの場合

ソケットは、期待どおりのrecv呼び出し中に、期待どおりに非ブロッキングソケットのように動作します $sock->recv($message, 128);

ただし、デーモンの実行中にデータを受信して​​いるときにeth0のVIFが再構成されると、recv呼び出しがブロックを開始することを一貫して観察しています。

これは非常に厄介な問題です。私はそうしました$sock->recv($message, 128, MSG_DONTWAIT);、そして、recv呼び出しは非ブロッキングになります。

私はグーグルで検索しましたが、UDPノンブロッキングソケットを使用するための推奨される方法がわかりませんでした。

4

1 に答える 1

4

まず、文字通りの答え:

# 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を使用することを強くお勧めします!

于 2012-11-12T18:50:16.973 に答える