6

少し蒸留すると、次のように見えるperlスクリプトがあります。

my $randport = int(10000 + rand(1000));          # Random port as other scripts like this run at the same time
my $localip = '192.168.100.' . ($port - 4000);   # Don't ask... backwards compatibility
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &");    # create the tunnel in the background

sleep 10;       # Give the tunnel some time to come up

# Create the telnet object
my $telnet = new Net::Telnet(
        Timeout =>      10,
        Host    =>      'localhost',
        Port    =>      $randport,
        Telnetmode =>   0,
        Errmode =>      \&fail,
);

# SNIPPED... a bunch of parsing data from $telnet

問題は、ターゲット $ip が非常に予測不可能な帯域幅を持つリンク上にあるため、トンネルがすぐにアップする可能性があることです。しばらく時間がかかる可能性があり、まったくアップしない可能性があります。そのため、トンネルを起動して実行するための時間を確保するために、スリープが必要です。

問題は、トンネルが稼働しているかどうかをテストするにはどうすればよいかということです。トンネルがすぐにアップする場合、10 秒は本当に望ましくない遅延です。理想的には、それが稼働しているかどうかを確認し、telnet オブジェクトの作成を最大 30 秒まで続けたいと考えています。

編集:トンネルのリモートエンドは一般的にアップしていますが、パケットロスが非常に多いため、Pingは私が口を開くのに役立ちません

解決済み: mikebabcock によって提案されたヒントからの外挿はsleep 10、魅力のように機能する次のブロックに置き換えられました。

my $starttime = time();
while (1)
{
    # Check for success
    if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last }

    # Check for timeout
    if (time() > $starttime + 30) { &fail() }

    # 250ms delay before recheck
    select (undef, undef, undef, 0.25);
}
4

3 に答える 3

6

netcatを使用する-多くncの場合、Linuxシステムでは次のようになります。

nc -dvzw10 ${HOSTNAME} 23

私のために働き、次のような応答があります:

Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded!

また、成功すると0を返し、単純な接続に満足し、その後は消えます。

  • -dは、キーボード側から何も読み取らないことを意味します
  • -vは冗長であることを意味します(スクリプトでこれをオフにします)
  • -zは、接続後に切断することを意味します
  • -w10は、最大10秒待機することを意味します。それ以外の場合は、あきらめます。
于 2012-09-26T15:43:17.113 に答える
1

ping を ssh サーバーに統合することができます。正常に動作する場合は、ssh トンネルが稼働しています。

# only a ping sample :-D
if !  ping -c 1 192.168.101.9
then
        echo ":-("
else
        echo ":-)"
fi
于 2012-09-26T15:34:50.133 に答える
0

fping は通常の ping よりも優れていると思います。よりスクリプトに適しています。

fping -t 60000 [あなたのサーバー]

あきらめる60秒前にサーバーへの接続を試行する必要があります

if(fping -t 60000 [your server]) {
execute desired code;
} else {
execute this script again to rerun;;
}

コーディングが本物でなくても、アイデアが得られると思います。

于 2012-09-26T15:36:52.157 に答える