0

请参阅底部的编辑以获取更多信息!

我有两台服务器。两者都应该能够通过 GET 请求相互调用。为了发出请求(它比实际发出请求更触发事件)我正在使用以下代码:

function URLCallAsync($url, $params, $type='POST')
{
      foreach ($params as $key => &$val) {
        if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
      }
  $post_string = implode('&', $post_params);

  $parts=parse_url($url);

  $fp = fsockopen($parts['host'],
      isset($parts['port'])?$parts['port']:80,
      $errno, $errstr, 30);

  // Data goes in the path for a GET request
  if('GET' == $type) $parts['path'] .= '?'.$post_string;

  $out = "$type ".$parts['path']." HTTP/1.1\r\n";
  $out.= "Host: ".$parts['host']."\r\n";
  $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
  $out.= "Content-Length: ".strlen($post_string)."\r\n";
  $out.= "Connection: Close\r\n\r\n";
  // Data goes in the request body for a POST request
  if ('POST' == $type && isset($post_string)) $out.= $post_string;

  fwrite($fp, $out);
  fclose($fp);
}

我在两台服务器上为函数提供了完全相同的数据(但 url)(我复制了调用文件来测试它!!)但它只能在一个方向上工作!

我将对该函数的调用写入日志文件中,以便调查是否出现问题。

服务器 A -> 服务器 B,工作正常,服务器 A 的日志文件包含正确的 url

服务器 B -> 服务器 A,只打印服务器 B 的日志文件中的正确信息,但服务器 A 从未收到请求。

这样的事情可能是什么原因?

编辑:可能是不同类型的服务器吗?服务器 A 是 nginx,服务器 B 是 apache。服务器 A 的 url 中也有一个 '~' 符号,也许这就是问题所在?获取请求的参数是用 php 的“urlencode”编码的,这可能会产生问题吗?

我试了一下,但问题仍然是请求没有到达服务器 A。但是从浏览器它以某种方式完美地工作(假设我输入带有参数的正确 URL)。

edit2:如果我将“URLCallAsync”与“file_get_contents”交换,它会正常工作。但问题是 file_get_contents 被阻塞了!所以它只能是函数本身。但奇怪的是它在相反的方向工作:(

编辑3:“URLCallAsync”函数在没有错误、通知或其他任何内容的情况下运行。它只是没有被其他服务器接收。file_get_contents 到底有什么不同???

4

1 回答 1

0

我让它工作了。

经过大量摆弄wireshark后,我发现file_get_contents比我的异步函数还要简单!

它只是完全省略了 Content-Length 字段!它只提供“GET ...”和“Host”。它还使用 HTTP/1.0 而不是 1.1,但这并没有改变任何东西。

所以解决方案是:同时发布 Content-Length 标头(其值为 0,因为我使用了 GET)将以某种方式使服务器拒绝请求。我不确定是服务器拒绝了请求,还是其他东西,比如可能检测到“格式错误”请求的防火墙,但至少问题得到了解决。

所以下次发送请求时,如果不需要,请不要提供 Content-Length 标头:)

于 2012-08-01T01:27:14.063 回答