5

私はperlを使用しています(うまくいけば何にも影響しないはずです)が、接続操作のタイムアウトを設定する方法を知る必要があります。問題は、接続操作が発生するのを永遠に待つことができないことです。それが数秒以内に起こらなければ、私はむしろあきらめて先に進みたいと思います。

socket(my $sock, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]);
setsockopt($sock, SOL_SOCKET, SO_SNDTIMEO, 10); # send timeout

print "connecting...\n";
connect($sock, sockaddr_in(80,scalar gethostbyname('lossy.host.com')));
print "connected...\n";

問題は、「lossy.host.com」への接続が「不可逆」であるか、遅いか、または高速ではない場合、ユーザーを待たせるよりもあきらめたいということです。(他のことを行うプログラムの副作用と考えてください...ユーザーはおそらく、このスクリプトがどこかのサーバーと通信することを期待していません...)。

スレッドの場合:connect()をどのように中断しますか?スレッドを外して忘れてしまいませんか?

4

3 に答える 3

2

を使用fcntlして、ソケットを非ブロックに設定selectし、タイムアウトで読み取り可能になるのを待つことができます。タイムアウト前に読み取れない場合は、その時点で閉じることができます。

C でこれを行う方法は知っていますが、perl ではわかりません。それ以外の場合は、例を挙げます。perlfunc のマンページには、これらの関数はすべて存在すると書かれています。

編集: 申し訳ありませんが、perlfunc が Unix 以外のシステムでは利用できない可能性があると述べている部分を見逃しており、実際、fcntlwin32 では利用できません。ただし、Windowsで正しいことを行う、使用できるIO::Socketライブラリがあります。

これが私のために機能するサンプルコードです(とにかくLinuxで):

#!/usr/bin/perl

use IO::Socket::INET;
use IO::Select;

$sock = IO::Socket::INET->new('PeerAddr' => 'lossy.host.com',
                              'PeerPort' => 80,
                              'Blocking' => 0 );

$sel = IO::Select->new( $sock );

@writes = $sel->can_write(10);

if ( $sock->connected ) {
    print "socket is connected\n";
} else {
    print "socket not connected after however long\n";
    $sock->close;
}
于 2010-02-17T20:44:44.103 に答える
1

別のスレッドを生成してそれを実行し、結果を待機するタイミングを実行することができます。適切な時間内に結果が得られない場合は、待機をあきらめて、スレッドを続行してください。最終的にタイムアウトになるか、スレッドを強制終了できる可能性があります。

connect()最初の質問に答えるために、少なくともソケットAPIを介して、タイムアウトを変更する方法はないと思います。Windowsでは、変更できるレジストリキーがあり、それに影響を与える可能性がある場合でも驚かないでしょうが、それが何であるかはわかりません。

于 2010-01-11T18:31:11.183 に答える