最近要做一個 測試IP列表 是否能連通的功能。大家都知道我們一般用 ping 命令就可以看到IP端口可不可以連通。那在程序里要怎么做呢?
我們在網上找到很多都是使用 exec("ping XXX") 的方式,然而這種方式有很大的安全隱患,exec() 是直接執行一個shell指令。由於其危險性,甚至很多公司都把此函數禁用了。況且就算不考慮其安全性,執行一個 ping 命令,它的等待返回都要好幾秒鍾(參考命令行的ping),這樣的做法也並不理想。
那么除了調用系統的ping命令,我們還有什么辦法來連接其它的IP呢?當然是有的。
1. curl 是一種遠程獲取文件的方式之一。但見其名可知,url,也就是說所連接的是一個網址,而必須那個網址上有一個可訪問的文件或者API接口。但是測試我們的IP,並不一定在其下有一個文件或者可以訪問,所以並不是一個好的方案。
2. socket 是一種兩台機器間進行通信的協議,其中又分為客戶端和服務端。它是先建立連接,再進行數據傳送。那也可以說,我們可以只建立連接,而不進行數據傳輸。

所以,最終的實現思路是。用PHP模擬成一個socket客戶端,連接指定的計算機端口(默認為 80 吧),然后就能判斷是否能能連通了。代碼如下:
<?php //ping一個IP地址,能不能通 function ping($ip){ $ip_port = explode(':', $ip); // var_dump($ip_port); if( filter_var( $ip_port[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ){ //IPv6 $socket = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP); }elseif( filter_var( $ip_port[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ){ //IPv4 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); }else{ return FALSE; } if( !isset($ip_port[1]) ){ //沒有寫端口則指定為80 $ip_port[1] = '80'; } $ok = socket_connect($socket, $ip_port[0], $ip_port[1]); // var_dump( socket_strerror( socket_last_error($socket) ) ); socket_close($socket); // var_dump($ok); return $ok; }
