我正在接收通过UDP发送到我的服务器的数据包。我正在使用socket_read来读取数据并且它正好相应。但是我遇到了一个错误。在我的情况下,socket_read的长度参数并不总是相同的。数据长度范围为50-150字节。保持不变的一件事是数据集以\ x00字节结束。在遇到这个字节之前,如何让read函数始终读取?我已经尝试过PHP_NORMAL_READ标志,但文档说它只在\ n或\ r \ n结束,这真的不是我想要的(试过它对我的数据不起作用)。同时,socket_read的php页面在 length 参数描述中声明,
读取的最大字节数为 由length参数指定。 否则,您可以使用\ r,\ n或\ 0来 结束阅读(取决于类型 参数,见下文)。
该类型没有说明/ 0字节。它就像缺少一份文件。我需要的是一个函数,它将让我为我的数据指定一个分隔符,将自动从可用的套接字读取所有数据。 socket_recv函数中可能有一个解决方案,但它没有文档,我不知道它是如何工作的。
提前致谢。
答案 0 :(得分:4)
如果我理解正确,你想从套接字中读取数据,直到没有更多数据要读取,问题是数据量是可变的,你不知道何时停止。
根据相关手册页(http://php.net/socket_read):
注意:socket_read()返回零 长度字符串(“”)没有时 更多要阅读的数据。
您应该能够通过逐字节读取来处理可变长度数据,直到您达到零长度字符串:
while (($currentByte = socket_read($socket, 1)) != "") {
// Do whatever you wish with the current byte
}
答案 1 :(得分:0)
处理读取有效负载的应用程序需要识别何时到达“记录结束”以查找正在传递的任何应用程序消息。阅读时期望任意长度。
小心使用UDP,因为如果您尝试将多个读取流式传输到消息中,则无法保证读取的数据包的顺序是由对等方发送的顺序。在这种情况下,建议使用TCP套接字。
答案 2 :(得分:0)
你试过这样的事情:
do {
echo socket_read($handle,1024);
$status = socket_get_status($handle);
} while($status['unread_bytes']);
答案 3 :(得分:0)
遇到了另一种可能适用于您的方法:
<?php
function tftp_fetch($host, $filename)
{
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
// create the request packet
$packet = chr(0) . chr(1) . $filename . chr(0) . 'octet' . chr(0);
// UDP is connectionless, so we just send on it.
socket_sendto($socket, $packet, strlen($packet), 0x100, $host, 69);
$buffer = '';
$port = '';
$ret = '';
do
{
// $buffer and $port both come back with information for the ack
// 516 = 4 bytes for the header + 512 bytes of data
socket_recvfrom($socket, $buffer, 516, 0, $host, $port);
// add the block number from the data packet to the ack packet
$packet = chr(0) . chr(4) . substr($buffer, 2, 2);
// send ack
socket_sendto($socket, $packet, strlen($packet), 0, $host, $port);
// append the data to the return variable
// for large files this function should take a file handle as an arg
$ret .= substr($buffer, 4);
}
while(strlen($buffer) == 516); // the first non-full packet is the last.
return $ret;
}
?>
这种方法最有趣的部分是:
do
...
while(strlen($buffer) == 516); // the first non-full packet is the last.