2010-01-30 80 views
5

我正在尝试编写一个工具来检查代理服务器是否启动并可供使用。到目前为止,我已经在下面的类中提出了两种方法(我删除了对这个问题是多余的setter和getters)。检测代理服务器是否可用的最佳方法是什么?

第一种方法使用cURL并尝试通过代理请求一个页面,第二个工具使用fsockopen并试图打开到代理的连接。

class ProxyList { 
    /** 
    * You could set this to localhost, depending on your environment 
    * @var string The URL that the proxy validation method will use to check proxies agains 
    * @see ProxyList::validate() 
    */ 
    const VALIDATION_URL = "http://m.www.yahoo.com/robots.txt"; 
    const TIMEOUT  = 3; 

    private static $valid = array(); // Checked and valid proxies 
    private $proxies  = array(); // An array of proxies to check 

    public function validate($useCache=true) { 
     $mh  = curl_multi_init(); 
     $ch  = null; 
     $handles = array(); 
     $delay = count($this->proxies) * 10000; 
     $running = null; 
     $proxies = array(); 
     $response = null; 

     foreach ($this->proxies as $p) { 
      // Using the cache and the proxy already exists? Skip the rest of this crap 
      if ($useCache && !empty(self::$valid[$p])) { 
       $proxies[] = $p; 
       continue; 
      } 

      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 
      curl_setopt($ch, CURLOPT_URL,    self::VALIDATION_URL); 
      curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true); 
      curl_setopt($ch, CURLOPT_PROXY,   $p); 
      curl_setopt($ch, CURLOPT_NOBODY,   true); // Also sets request method to HEAD 
      curl_setopt($ch, CURLOPT_HEADER,   false); 
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
      curl_setopt($ch, CURLOPT_TIMEOUT,   self::TIMEOUT); 

      curl_multi_add_handle($mh, $ch); 
      $handles[$p] = $ch; 
     } 

     // Execute the multi-handle 
     do { 
      curl_multi_exec($mh, $running); 
      usleep($delay); 
     } while ($running); 

     // Get the results of the requests 
     foreach ($handles as $proxy => $ch) { 
      $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); 

      // Great success 
      if ($status >= 200 && $status < 300) { 
       self::$valid[$proxy] = true; 
       $proxies[] = $proxy; 
      } 
      else { 
       self::$valid[$proxy] = false; 
      } 

      // Cleanup individual handle 
      curl_multi_remove_handle($mh, $ch); 
     } 

     // Cleanup multiple handle 
     curl_multi_close($mh); 

     return $this->proxies = $proxies; 
    } 

    public function validate2($useCache=true) { 
     $proxies = array(); 

     foreach ($this->proxies as $proxy) { 
      // Using the cache and the proxy already exists? Skip the rest of this crap 
      if ($useCache && !empty(self::$valid[$proxy])) { 
       $proxies[] = $proxy; 
       continue; 
      } 

      list($host, $post) = explode(":", $proxy); 

      if ($conn = @fsockopen($host, $post, $errno, $error, self::TIMEOUT)) { 
       self::$valid[$proxy] = true; 
       $proxies[] = $proxy; 
       fclose($conn); 
      } else { 
       self::$valid[$proxy] = false; 
      } 
     } 

     return $this->proxies = $proxies; 
    } 
} 

到目前为止,我更喜欢cURL方法,因为它可以让我像fsockopen一次检查代理的大批量并行,这是邪恶的快,而不是一个。

我还没有做很多与代理工作,所以我很难判断这些方法是否足以验证代理是否可用,或者是否有更好的方法使我缺失。

+0

哇,伙计,漂亮的图片! – 2010-01-30 09:00:54

+0

哈哈,谢谢 – 2010-01-30 09:07:01

回答

1

嗯。试图通过代理与安全(最可能是可用的)URL建立连接,并检查错误,听起来就像o.k.对我来说。

为了确保最大的安全性,您可能希望将另一个调用添加到另一个验证网址(例如Google的某个网址),或者为了以防万一,请将其设为两个呼叫。

+0

第二次可用性检查听起来不错,但是提出的请求越多,性能就越受关注。 – 2010-01-30 09:37:09

+0

是的。这取决于预期的用途,我猜。 – 2010-01-30 09:48:20

1

cURL是首选方法,因为multi_exec。

我不会打扰做两个检查,但立即执行谷歌(或一个Proxyjudge)调用。 代理有时可以允许套接字,但只是不会获取一个东西:因此,你的cURL方法将是安全的,而不是那么慢。

由于上面的Pekka提到:它取决于预期用途。

您是否使用Charon并收获了代理负载,我希望他们通过代理判断进行检查,并且我想知道转换时间(以避免缓慢的代理)和anonimity。

如果你想使用它作为企业代理的监控系统,我只想确保它可以获取一个页面。

a(混沌)通过使用cURL获取URL来检查代理的示例。

TLDR:使用cURL,它可以处理并行请求,并且最稳定而不会减慢(通过不执行doublecheck)。 http://www.oooff.com/php-affiliate-seo-blog/php-automation-coding/easy-php-proxy-checker-writing-tutorial/

相关问题