PHP Sockets 半工作

发布于 2024-10-15 18:28:56 字数 1768 浏览 5 评论 0原文

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

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

该脚本的工作方式是正确的: 1)连接到1235端口 2)它发送$i 2.1)但在另一边没有收到消息(又名我收到袜子读取事件,但没有弹出任何文本) 3)它正确读取所有传入消息 4)当消息为“end”时关闭 鼓声 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);
?>

这就是我在说“end”后在浏览器中得到的内容

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

这是在 mIRC 中:

测试:89.152.172.21 已加入! 读 关闭 块引用

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

So, i have mIRC making a listen (bear with me on this one) on port 1235 and i tried to make a php script to connect to such port on my localhost server.

My localhost is a clean Apache+PHP with mIRC being run on another computer (inside lan).

The script works half-right as:
1) it connects to the 1235 port
2) it sends the $i
2.1) but on the other side no msg is recieved (aka I get a sock read event but no text pops up)
3) it reads all the incoming messages correclty
4) it closes when 'end' is the message
drumroll
5) it only works IF the while function isn't present.
5.1) aka Inifi-loading. it only shows echo when socket is closed via 'end'

here is the code, which is a simple example i found on php.net, thanks in advance :)

    <?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);
?>

this is what i get in browser, after saying 'end'

socket successfully created.
Attempting to connect to
'192.168.1.101' on port
'1235'...successfully connected to
192.168.1.101. Sending 1 to server. Response from server is: ok
Response from server is: end

this is in mIRC:

test: 89.152.172.21 is in!
read
close
Blockquote

if i had left it working for an hour, multiply "read" for 60 and "sending N+1 to server"
but this only shows up AFTER sock close (or by stoping the while)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦旅人picnic 2024-10-22 18:28:56

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

PHP 手册引用:

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

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

读书也是如此。读取调用可以读取您请求的内容或更少,并且您需要重试该调用。

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


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

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

You have "plain" socket_write() and socket_read() calls. Unfortunately socket functions are unreliable by design (that's behavior inherited from BSD sockets). You can't just call socket_write() and expect it to actually write bytes (as odd as it sounds…)

PHP manual quote:

socket_write() does not necessarily write all bytes from the given buffer. It's valid that, depending on the network buffers etc., only a certain amount of data, even one byte, is written though your buffer is greater. You have to watch out so you don't unintentionally forget to transmit the rest of your data.

You have to check how many bytes have been written and keep retrying until all you wanted has been sent.

The same goes for reading. Read call can read as much as you requested or less and you're expected to retry the call.

Make sure to set sockets to blocking and then call read/write in a loop, or use (equally awful) select() call to find which sockets may have some data or may have finished sending.


If you want API that's not such PITA, then use streams instead, which have reliable reads/writes.

If you don't necessarily need PHP, then have a look at Node JS, which is specially designed server/environment for programs with long-lived network connections.

泼猴你往哪里跑 2024-10-22 18:28:56

更改

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

为:

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

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

Change

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

To:

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

You are providing an integer where PHP expects a string.

⊕婉儿 2024-10-22 18:28:56

来自文档中的注释之一:
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);

From one of the notes in the documentation:
http://php.net/manual/en/function.socket-write.php

Some clients (Flash's XMLSocket for example) won't fire a read event until a new line is recieved.

So try changing your code:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文