在共享主机提供程序上使用socket_bind()时出错

时间:2015-02-28 16:45:30

标签: php sockets

我有一个使用PHP的套接字API用PHP编写的服务器服务脚本和客户端服务脚本。它们在localhost中工作正常,但在将这两个脚本上传到ipage上的主机帐户后,服务器脚本在socket_bind调用时给出了错误。这是我在服务器上使用的代码:

$host = "my_own_hosting"; 
$port = 25003; 
$message = "Hello Client"; 
set_time_limit(0); 
// create socket 
$socket = socket_create(AF_INET, SOCK_STREAM, 0) 
    or die("Could not create socket\n"); 
// bind socket to port (this is the call that returns the error)
$result = socket_bind($socket, $host, $port) 
    or die("Could not bind to socket\n");
// put server into passive state and listen for connections 
$result = socket_listen($socket, 3) 
    or die("Could not set up socket listener\n");

有关此通话无效的任何想法?

1 个答案:

答案 0 :(得分:1)

首先是:

使用socket_strerrorsocket_last_error来解决您的问题:

if (!($result = socket_bind($socket, $host, $port)){ 
    die(socket_strerror(socket_last_error($socket)));
}

您正尝试在共享的PHP托管服务提供商(ipage)上运行您的服务器脚本。

这类提供程序通常不允许使用PHP套接字接口来构建您自己的服务,或实施严格的限制(例如允许的端口或运行服务的协议)以避免滥用并防止出现安全问题。您要么遵守它们,要么将托管服务更改为符合您需求的托管服务。

您的提供商似乎允许使用套接字接口。

(您可以通过在http://www.hostingreviewbox.com/features/ipage-php/上搜索套接字来查看它,但最好是通过自己在帐户上运行phpinfo来确定它,或者更好:打开支持票您的托管服务提供商,并询问他们您的帐户是否以任何方式限制套接字。)

然后你应该确定两件事:

  1. 您是否在$host上使用了正确的IP地址?
  2. 您可以ping my_own_hosting并查看您获得的内容甚至更好,将此代码段添加到您的服务器脚本中,以便在运行时确定服务器的公共IP:

      $host = my_ip();
      echo "my ip address is $host\n";
    
      function my_ip($dest='8.8.8.8', $port=53)
      {
        $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
        socket_connect($socket, $dest, $port);
        socket_getsockname($socket, $addr, $port);
        socket_close($socket);
        return $addr;
      }
    

    (来自http://php.net/manual/en/function.socket-create.php#49368

    1. 您尝试使用的端口是否已在使用或受限制?
    2. 尝试使用其他端口或询问您的托管服务提供商。

      旁注:

      在评论之前信任PHP手册:您应该使用getprotobynameSOL_TCP来确定socket_create的第三个参数,而不是仅发送0 < / p>

      最后,您应考虑使用socket_create_listen 而不是socket_create + socket_bind + socket_listen。或者,对于这种特殊情况,stream_socket_serverstream_socket_accept。与PHP手册一样,它们更实用:

      $socket = stream_socket_server("tcp://{$host}:{$port}", $errno, $errstr);
      if (!$socket) {
        echo "$errstr ($errno)<br />\n";
      } else {
        while ($conn = stream_socket_accept($socket)) {
          fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
          fclose($conn);
        }
        fclose($socket);
      }