我正在尝试通过套接字将JSON数据从一个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"answers"''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";
}
}
您对其他套接字使用socket_write函数。当您添加EOF字符时,仅用于其他套接字recv。但您必须知道带有用于recv的socket_write的EOF字符并将其分解。