2013-12-03 17 views
5

ここでは、ポートが開いているかどうかを調べるために使用しているコードを示します。ソケットを使用してTCP接続を返すfalse結果

https://stackoverflow.com/a/8957053/2203703

誰もがそれを修正してくださいしようとしてもらえますか?ここで私はポート80

79.142.126.3 //Connection refused 
222.165.195.103 //Connection refused 
64.75.193.162 //Connection refused 
118.97.197.146 //Port is open 
222.134.154.103 //Connection timed out 
173.0.59.170 //Port is open 

そして、ここでそれをテストしているIPリストが出力されているポートがオフになっている場合でも、コードは常に「正常に接続」

を返し、正常に動作しないようです:

5 sockets connected successfully 
79.142.126.3 connected successfully 
222.165.195.103 connected successfully 
64.75.193.162 connected successfully 
118.97.197.146 connected successfully 
173.0.59.170 connected successfully 

コードは正常に見えますが、実際には問題が見つかりません。

お願いします。

+1

、あなたたちなかった理由他の回答の1つ(29票と賞金のあるもののようなもの)? –

+0

カールは良いですが、ソケットもすばらしく速く、それは私のための最良のオプションです。 – user2203703

答えて

0

このコードは...とにかく、また失敗...

にあなたがecho "$count sockets connected successfully\n"echo "$address connected successfully\n"は、任意の条件に応じていないことを確認できる「succesfuly」プリントアウトし

のみecho "Created socket for $address\n"は、状況に応じているが、ポートが閉じているときにもソケットを作成できます。

問題はありません。一般的なメッセージ "Xソケットが正常に接続されました"が印刷されます(それを削除することはできます)が、 "XXXXX connected successfully"という特定のメッセージは印刷されません!

+0

これを修正する方法はありますか?ありがとう。 – user2203703

+0

私の更新された回答を参照してください。これはあなたの国家ではない? – MeNa

+0

@ user2203703あなたが( '$ addresses'配列で)単一のIPアドレスだけを(そしてこのIPのポート80は閉じていれば)正確な出力を表示してください。 – MeNa

7

私がノンブロッキングI/Oの多くの側面を限定的に理解していたとき、あなたがリンクしたコードはずっと前に書かれました。

実際には多くの実装があるイベントループが必要ですが、この例では@rdlowreyAlertライブラリを使用します。これは、理解しやすい最小限のコードであるためです。 Reactにループを張ることもできます。これはより高いレベルであり、より多くの機能を提供します。

注以下の例では、PHP 5.4+

<?php 

// Array of addresses to test 
$addresses = [ 
    '192.168.5.150', 
    '192.168.5.152', 
    'google.com', // Important note: DNS is resolved synchronously here. 
    '192.168.5.155', // this can seriously slow down the process as it can block 
    '192.168.5.20', // for a few seconds, async DNS resolution is non-trivial 
    '192.168.40.40', // though 
]; 
// The TCP port to test 
$port = 80; 
// The length of time in seconds to allow host to respond 
$timeout = 5; 

// This will hold the results 
$lookups = []; 

// Create a reactor 
$reactor = (new \Alert\ReactorFactory)->select(); 

$count = count($addresses); 
$completedCount = 0; 

$onComplete = function($address, $result) 
        use(&$lookups, &$completedCount, $count, $reactor) { 

    // Cancel the watchers for this address 
    $reactor->cancel($lookups[$address]['failWatcher']); 
    $reactor->cancel($lookups[$address]['writeWatcher']); 
    $reactor->cancel($lookups[$address]['readWatcher']); 

    // Store the result 
    $lookups[$address] = $result; 

    // If there's nothing left to do, stop the reactor 
    if (++$completedCount == $count) { 
     $reactor->stop(); 
    } 
}; 

foreach ($addresses as $address) { 
    // Normalise the address to lower-case, as it will be used as an array key 
    $address = strtolower($address); 

    if (!isset($lookups[$address])) { 
     // Create a socket to connect asynchronously 
     $sockAddr = "tcp://{$address}:{$port}"; 
     $flags = STREAM_CLIENT_ASYNC_CONNECT; 
     $socket = stream_socket_client($sockAddr, $errNo, $errStr, 0, $flags); 
     stream_set_blocking($socket, 0); 

     // Set up a timeout to watch for failed connections 
     $failWatcher = function() use($address, $onComplete, $timeout) { 
      echo "{$address} connect failed: Connect timed out\n"; 
      $onComplete($address, false); 
     }; 
     $failWatcherId = $reactor->once($failWatcher, $timeout); 

     // Watch for the stream becoming writable (connection success) 
     $writeWatcher = function() use($address, $onComplete) { 
      echo "{$address} connected successfully\n"; 
      $onComplete($address, true); 
     }; 
     $writeWatcherId = $reactor->onWritable($socket, $writeWatcher); 

     // Watch for the stream becoming readable (success or explicit fail) 
     $readWatcher = function() use($address, $onComplete, $socket) { 
      if ('' === $data = fread($socket, 1024)) { 
       echo "{$address} connect failed: Server refused connection\n"; 
       $onComplete($address, false); 
      } else if ($data === false) { 
       echo "{$address} connect failed: Stream read error\n"; 
       $onComplete($address, false); 
      } else { 
       echo "{$address} connected successfully\n"; 
       $onComplete($address, true); 
      } 
     }; 
     $readWatcherId = $reactor->onReadable($socket, $readWatcher); 

     // Store the watcher IDs so they can be destroyed later 
     $lookups[$address] = [ 
      'failWatcher' => $failWatcherId, 
      'writeWatcher' => $writeWatcherId, 
      'readWatcher' => $readWatcherId, 
     ]; 
    } 
} 

// Set everything going 
$reactor->run(); 

// $lookups is now an array of booleans indicating whether the address resulted 
// in a successful connection 
0

が必要であることを、あなたは、あなたのコードを簡素化することができます(その後、並列に遅く明らかに、)IPS順をテストし、socket_connect機能から有用な応答を有するように余裕があれば:

<?php 

    // An array of hosts to check 
    $addresses = array(
    '79.142.126.3', //Connection refused 
    '222.165.195.103', //Connection refused 
    '64.75.193.162', //Connection refused 
    '118.97.197.146', //Port is open 
    '222.134.154.103', //Connection timed out 
    '173.0.59.170' //Port is open 
); 

    // The TCP port to test 
    $testport = 80; 
    // The length of time in seconds to allow host to respond 
    $timeout = 5; 

    foreach ($addresses as $address) { 

    if (!$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) { 
     echo "Could not create socket for $address\n"; 
     continue; 
    } 

    socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0)); 
    socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $timeout, 'usec' => 0)); 

    if (@socket_connect($sock, $address, $testport)) { 
     echo "$address connected successfully\n"; 
    } 
    else { 
     echo "Unable to connect to $address\n"; 
    } 
    } 

応答:好奇心のうち

Unable to conenct to 79.142.126.3 
Unable to conenct to 222.165.195.103 
Unable to conenct to 64.75.193.162 
118.97.197.146 connected successfully 
Unable to conenct to 222.134.154.103 
173.0.59.170 connected successfully 
関連する問題