我正在尝试在端口 8195 上制作一个简单的侦听器。当我在 PHP CLI 条件下尝试以下代码块时,它只显示"测试"一次,然后挂起。如果我删除文件"votifier.run",该文件被设计为开/关开关,它仍然继续挂起。它从不显示"客户端已连接"。
此外,如果我尝试在脚本运行时通过端口 8195 上的 Telnet 连接到主机,我只会收到连接失败消息。就像它在寻找一种联系,只是不放弃。
// Set the IP and port to listen to
$address = 'localhost';
$port = 8195;
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port);
// Start listening for connections
socket_listen($sock);
// Loop continuously
while ( file_exists('votifier.run') ) {
echo 'Test';
$client = socket_accept($sock);
if( $client ) {
echo 'Client connected';
// Don't hang on slow connections
socket_set_timeout($client, 5);
// Send them our version
socket_write("VOTIFIER MCWEBLINK'n");
// Read the 256 byte block
$block = socket_read($client, 256);
...
答案是:socket_accept() 通常会挂起,直到建立连接。如果进行了连接尝试,脚本将继续,但由于套接字是在 localhost 上创建的,因此它只接受来自 localhost 的连接。
解决方法是使用外部 IP,而不是"本地主机"或"127.0.0.1"。然后你可以远程登录到它。
我只是在这里猜测,但是您尝试绑定的地址不应该是主机名吗?
如果套接字属于AF_INET系列,则地址是点分四边形表示法的 IP(例如 127.0.0.1)。
编辑
好的,我已经采用了您的脚本并尝试重现您的错误,但无法重现。它有几个缺陷,但没有一个会导致telnet客户端的连接尝试失败。
由于上述都不适用,让我们一一浏览清单:
- 套接字模块加载/编译
- 本地主机解析为 127.0.0.1
- 该端口未被正在运行的任何其他应用程序占用
- 没有任何防火墙规则会阻止Telnet客户端和服务器之间的通信
- 允许您连接的计算机连接到服务器主机(如果不是,请尝试使用同一主机)
- 在 while 循环中检查的文件确实存在 您
- 确定脚本中没有其他致命错误会阻止您发布的代码段运行
这些都是我能想到的可能的错误源,atm。 首先尝试修复小缺陷,然后通过清单。
if( $client ) {
echo 'Client connected';
// Don't hang on slow connections
socket_set_option(
$client,
SOL_SOCKET,
SO_RCVTIMEO | SO_SNDTIMEO,
array('sec' => 5, 'usec' => 0)
);
// Send them our version
socket_write($client, "VOTIFIER MCWEBLINK'n");
^^^^^^^
// Read the 256 byte block
$block = socket_read($client, 256);
你应该使用线程。如果客户端从不发送任何内容,您的代码将在 read() 方法中阻塞。每个接受的套接字都应在新线程中完全处理。
您可能需要检查以下内容:PHP Votifier 示例 Minecraft Topsites
它解释了代码的工作原理,它是进行加密、填充 256 个空格并发送数据包的基本功能。你可以使用它,因为你可能想改进它。
您可以在此处查看该插件正在运行的 php 的实时演示:http://topg.org/test_votifier