【问题标题】:PHP Sockets is half-workingPHP Sockets 工作一半
【发布时间】:2011-06-21 07:15:15
【问题描述】:

所以,我让 mIRC 在端口 1235 上进行侦听(请耐心等待),我尝试制作一个 php 脚本来连接到我的本地主机服务器上的此类端口。

我的 localhost 是一个干净的 Apache+PHP,mIRC 在另一台计算机(局域网内)上运行。

该脚本的工作方式有一半: 1)它连接到1235端口 2) 它发送 $i 2.1)但另一方面没有收到味精(也就是我收到一个袜子读取事件,但没有弹出文本) 3)它正确读取所有传入的消息 4)当“结束”是消息时它关闭 鼓声 5) 仅当 while 函数不存在时才有效。 5.1)又名 Inifi 加载。它只在通过'end'关闭套接字时显示回声

这是代码,这是我在 php.net 上找到的一个简单示例,在此先感谢 :)

    <?php
//The Client
error_reporting(E_ALL);

$address = "192.168.1.101";
$port = 1235;

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
    echo "socket successfully created.\n";
}

echo "Attempting to connect to '$address' on port '$port'...";
$result = socket_connect($socket, $address, $port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
    echo "successfully connected to $address.\n<br>";
}
$allow = true;
$i = 0;
while ($allow == true)
{
    $i++;
    echo "Sending $i to server.\n<br>";
    socket_write($socket, $i, strlen($i));

    $input = socket_read($socket, 2048);
    if ($input == 'end') {
        $allow = false; 
    }
    echo "Response from server is: $input\n";
    sleep(5);
}

echo "Closing socket...";
socket_close($socket);
?>

这是我在浏览器中看到的,在说“结束”之后

套接字成功创建。 尝试连接到 端口上的“192.168.1.101” '1235'...成功连接到 192.168.1.101。发送 1 到服务器。来自服务器的响应是:好的 来自服务器的响应是:结束

这是在 mIRC 中:

测试:89.152.172.21 在! 读 关闭 块引用

如果我让它工作了一个小时,将“读取”乘以 60 并“发送 N+1 到服务器” 但这只会在 sock close 后显示(或通过一段时间停止)

【问题讨论】:

  • 您可以发布运行时吐出的echos 内容吗?可能有助于调试它。
  • 更新了帖子以吐出echos :)

标签: php sockets chat


【解决方案1】:

你有“普通”的socket_write()socket_read() 电话。不幸的是,套接字函数在设计上并不可靠(这是从 BSD 套接字继承的行为)。您不能只调用 socket_write() 并期望它实际写入字节(听起来很奇怪……)

PHP手册引用:

socket_write() 不一定要从给定缓冲区写入所有字节。有效的是,根据网络缓冲区等,尽管您的缓冲区更大,但仅写入一定数量的数据,甚至是一个字节。您必须小心,以免无意中忘记传输其余数据。

您必须检查已写入的字节数并不断重试,直到发送完您想要的所有字节。

阅读也是如此。读取调用可以读取与您请求的一样多或更少,并且您需要重试调用。

确保将套接字设置为阻塞,然后在循环中调用读/写,或者使用(同样糟糕的)select() 调用来查找哪些套接字可能有一些数据或可能 发送完毕。


如果您想要的 API 不是这样的 PITA,请改用 streams,它具有可靠的读/写功能。

如果您不一定需要 PHP,那么请查看 Node JS,它是专门为具有长期网络连接的程序设计的服务器/环境。

【讨论】:

  • 这解释了很多。另外,感谢您提供如此详细的答案 - 我已经失去了让这个功能发挥作用的希望:) 会做并检查流,因为它似乎更容易并且还会检查 Node.js,因为它听起来正是我想要的
【解决方案2】:

来自文档中的注释之一: http://php.net/manual/en/function.socket-write.php

某些客户端(例如 Flash 的 XMLSocket)在收到新行之前不会触发读取事件。

所以尝试更改您的代码:

socket_write($socket, $i, strlen($i)); 到: socket_write($socket, $i.'\n', strlen($i)+1);

【讨论】:

  • 双引号表示真正的换行符。
【解决方案3】:

改变

socket_write($socket, $i, strlen($i));

收件人:

socket_write($socket, strval($i), strlen(strval($i)));

您正在提供一个整数,而 PHP 需要一个字符串。

【讨论】:

  • 即使是这样,我仍然在 mIRC 上得到 0Rcvd 字节
猜你喜欢
  • 2010-10-09
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 2015-06-07
  • 2011-12-14
  • 1970-01-01
相关资源
最近更新 更多