我正在尝试通过套接字将JSON数据从一个PHP脚本发送到另一个PHP脚本。以下是客户端代码
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
@socket_connect($socket, "localhost", 2429) or die("Connect could not be opened");
$arr = ["Hello", "I", "am", "a", "client"];
$count = 10;
while($count-- > 0) {
$msg = json_encode(["msg" => $arr[rand(0, 4)]]);
// tried appending \n & \0
// $msg .= "\0"; // "\n";
echo "sending $msg \n";
socket_write($socket, $msg, strlen($msg));
}
以下代码是处理接收的服务器:
$count = 0;
while(socket_recv($feed, $buf, 1024, 0) >= 1) {
echo "Obj ".++$count." : $buf";
// $obj = json_decode($buf); // error
}
问题是,在套接字服务器端,由于以下情况,json_decode无法解析数据:
预期输出:
Obj 1: {"msg":"I"}
Obj 2: {"msg":"a"}
Obj 3: {"msg":"a"}
Obj 4: {"msg":"I"}
Obj 5: {"msg":"a"}
Obj 6: {"msg":"client"}
Obj 7: {"msg":"am"}
Obj 8: {"msg":"am"}
Obj 9: {"msg":"am"}
我得到的输出:
Obj 1: {"msg":"I"}{"msg":"a"}{"msg":"a"}{"msg":"I"}
Obj 2: {"msg":"a"}{"msg":"client"}{"msg":"am"}{"msg":"am"}
Obj 3: {"msg":"am"}
我理解我需要在发送下一个服务器之前告诉服务器end of object
,但我不知道如何。我试图附加“\ n”和“\ 0”来告诉服务器端流,但它不起作用。请帮帮我的朋友。提前谢谢!
答案 0 :(得分:0)
让我们尝试添加一个长度标题,因为这是涉及字符串时最安全的方式。
您的客户需要发送该信息,因此您需要对原始代码稍作修改:$msg = strlen($msg) . $msg;
(在$msg = json_encode(["msg" => $arr[rand(0, 4)]]);
之后。
然后,假设$socket
被打开,请尝试将其作为服务器代码(不要忘记关闭套接字):
$lengthHeader = '';
$jsonLiteral = '';
while ($byte = socket_read($socket, 1)) { // reading one number at a time
echo "Read $byte\n";
if (is_numeric($byte)) { //
$lengthHeader .= $byte;
} else if ($lengthHeader) {
echo "JSON seems to start here. So...\n";
$nextMsgLength = $lengthHeader - 1; // except the current one we've just read (usually "[" or "{")
echo "Will grab the next $nextMsgLength bytes\n";
if (($partialJson = socket_read($socket, $nextMsgLength)) === false) {
die("Bad host, bad!");
}
$jsonLiteral = $byte . $partialJson;
$lengthHeader = ''; // reset the length header
echo "Grabbed JSON: $jsonLiteral\n";
} else {
echo "Nothing to grab\n";
}
}
答案 1 :(得分:-3)
你将socket_write函数用于其他套接字。当你添加EOF字符时,只是为其他套接字recv。但是你必须知道你的recv的socket_write的EOF字符并将其爆炸。