2013-12-03 16 views
5

Oto kody, których używam do skanowania portu, jeśli jest otwarty, czy nie.Połączenie TCP za pomocą powrotu do gniazda false wyniki

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

ktoś może próbować to naprawić proszę? nie wydaje się działać poprawnie, nawet jeśli port jest wyłączony, kody zawsze wrócić „pomyślnie podłączone”

Oto lista ip które ja testowałem go z portu 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 

I tu jest wyjście :

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 

Kody wyglądają dobrze, ale naprawdę nie mogę znaleźć problemu.

Proszę o pomoc?

+1

z ciekawości, dlaczego nam nie e jedna z innych odpowiedzi (jak ta z 29 głosami i nagrodą)? –

+0

curl jest dobry, jednak gniazdo też jest dobre, szybkie i jest dla mnie najlepszą opcją. – user2203703

Odpowiedz

0

Kod ten wypisuje „z sukcesem” i tak, również w przypadku awarii ..

Widać, że echo "$count sockets connected successfully\n" i echo "$address connected successfully\n" nie zależy od żadnych warunków ...

Tylko echo "Created socket for $address\n" się w zależności od stanu, ale gniazdo może zostać utworzone również po zamknięciu portu.

Nie widzę żadnego problemu. generowany jest komunikat "Połączone gniazda X pomyślnie" (można go usunąć ...), ale komunikat "XXXXX podłączony pomyślnie" nie zostanie wydrukowany!

+0

Każdy pomysł, jak to naprawić? dzięki. – user2203703

+0

Zobacz moją zaktualizowaną odpowiedź. To nie jest stan z tobą? – MeNa

+0

@ user2203703 Proszę podać dokładne dane wyjściowe, gdy umieszczasz (w tablicy '$ addresses') tylko jeden adres IP (a port 80 w tym IP jest zamknięty). – MeNa

7

Kod, który łączysz został napisany dawno temu, kiedy miałam ograniczone zrozumienie wielu aspektów nie blokujących operacji we/wy.

To naprawdę wymaga pętli zdarzeń, z których istnieje wiele implementacji, ale dla tego przykładu użyję biblioteki @rdlowreyAlert, ponieważ jest to kod minimalistyczny, który powinien być dość łatwy do zrozumienia. Możesz również wykonać pętlę pod numerem React, która jest na wyższym poziomie i zapewnia wiele innych funkcji.

Zauważ, że poniżej przykład wymaga 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

Jeśli możesz sobie pozwolić, aby przetestować ips sekwencyjnie (oczywiście wolniej następnie równolegle) następnie można uprościć swój kod i posiada użyteczną odpowiedź socket_connect funkcji :

<?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"; 
    } 
    } 

Response:

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 
Powiązane problemy