通过PHP套接字发送和接收多个JSON文本


Sending and receiving multiple JSON literals via PHP sockets

我正在尝试通过套接字将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字符并将其分解。