2

我正在尝试在端口 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 而不是“localhost”或“127.0.0.1”。然后你可以 Telnet 到它。

4

3 回答 3

3

我只是在这里猜测,但是您尝试绑定的地址可能不是主机名吗?

如果套接字属于 AF_INET 系列,则地址是采用点分四进制表示法的 IP(例如 127.0.0.1)。

编辑

好的,我已使用您的脚本并尝试重现您的错误,但无法重现。它有几个缺陷,但没有一个会导致 telnet 客户端的连接尝试失败。

由于上述都不适用,让我们一一检查清单:

  • 加载/编译的套接字模块
  • localhost 确实解析为 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);
于 2012-08-14T08:16:57.363 回答
0

你应该使用线程。如果客户端从不发送任何内容,您的代码将在 read() 方法中阻塞。每个接受的套接字都应该在一个新线程中完全处理。

于 2012-08-14T10:33:51.933 回答
-1

您可能想检查一下: Minecraft Topsites 的 PHP Votifier 示例

它解释了代码是如何工作的,它是进行加密、填充 256 个空格并发送数据包的基本功能。您可以使用它进行一些工作,因为您可能想要改进它。

您可以在此处查看该插件的运行 php 的现场演示:http: //topg.org/test_votifier

于 2012-11-02T16:38:49.017 回答