PHP套接字 - 只能从localhost连接(Port Forwarding问题?)

C-s*_*eed 1 php sockets daemon localhost

首先,感谢您花时间阅读本文.我有一个PHP套接字的奇怪问题.我正在开发一个通过localhost工作的php套接字守护进程,但是当我尝试从局域网或其他PC外部连接时,它不起作用.我已将我的守护进程简化为一个非常基本的套接字连接,以复制该问题供您查看.

基本上,这是Senario.我在端口6667上的服务器上启动套接字守护程序.我可以通过telnet和运行守护程序的本地计算机上的浏览器连接到守护程序,但是我无法从任何其他计算机连接 - 守护程序甚至看不到连接尝试正在制作

为了进一步使问题复杂化(这就是为什么我认为这是端口转发问题),我的ISP阻止端口80,所以我设置了dyndns和我的路由器使用端口8000.我还设置了我的路由器以将端口6667转发到我的服务器.

要从浏览器访问我的守护进程,请输入以下(seudo)url:

http://mydomain.com:8000/client.php
Run Code Online (Sandbox Code Playgroud)

这可以从本地计算机上运行并且将连接,但是从任何其他计算机,守护程序甚至看不到正在进行的连接尝试.但是,如果我指定这样的端口:

http://mydomain.com:6667
Run Code Online (Sandbox Code Playgroud)

我的守护进程确实看到了正在建立的连接,但当然浏览器没有加载客户端页面,用户可以使用该页面与守护进程进行交互.

我的客户端使用flash文件来创建套接字连接(jsocket),但我知道它不是跨域策略文件,因为策略是正确的,并且当通过localhost连接时,它正确地提供策略文件.

这是简化的守护程序代码:

 <? 

// set some variables 
$host = '0.0.0.0'; 
$port = 6667; 

// don't timeout! 
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 
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n"); 

// start listening for connections 
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n"); 

// accept incoming connections 
// spawn another socket to handle communication 
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n"); 

// read client input 
$input = socket_read($spawn, 1024) or die("Could not read input\n"); 

// clean up input string 
$input = trim($input); 

// echo input back 
$output = $input . "\n"; 
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n"); 

// close sockets 
socket_close($spawn); 
socket_close($socket); 
?>
Run Code Online (Sandbox Code Playgroud)

摘要:

我可以通过telnet和浏览器从localhost连接...我可以通过telnet从其他机器连接,但是当指定端口8000时,我无法使用ip或域名从其他机器连接浏览器.守护程序没有看到任何连接尝试.如果我指定端口6667,那么守护进程会看到连接尝试,但这对用户来说是无用的.:(

任何有关此事的帮助将不胜感激!谢谢!

net*_*der 8

您正在将套接字(使用socket_bind)绑定到localhost.提供localhost将有PHP将套接字绑定到127.0.0.1.

socket_bind用于将套接字绑定到特定接口.每个例子:

socket_bind($socket, '127.0.0.1', 80);
Run Code Online (Sandbox Code Playgroud)

这允许您连接到127.0.0.1:80,但不是192.168.1.100:80,即使它们是同一台机器.套接字仅绑定到127.0.0.1接口:

$ telnet localhost 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
$ telnet 192.168.1.100 80
Trying 192.168.1.100...
telnet: Unable to connect to remote host: Connection refused
Run Code Online (Sandbox Code Playgroud)

如果要在所有可用接口上绑定套接字,请使用:

socket_bind($socket, '0.0.0.0', 80);
Run Code Online (Sandbox Code Playgroud)

然后这工作:

$ telnet localhost 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
$ telnet 192.168.1.100 80
Trying 192.168.1.100...
Connected to 192.168.1.100.
Run Code Online (Sandbox Code Playgroud)