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

通过PHP套接字发送和接收多个JSON文本,php,json,sockets,Php,Json,Sockets,我正在尝试通过套接字将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($

我正在尝试通过套接字将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_解码无法解析数据:

预期产出:

我得到的输出:


我知道我需要在发送下一个对象之前告诉对象的服务器端,但我不知道如何发送。我试图附加\n和\0以告知流的服务器端,但它不起作用。请帮助我的朋友。提前谢谢你

对其他套接字使用socket\u write函数。当您添加EOF char时,它仅用于其他套接字recv。但是你必须知道你的recv的socket写入的EOF char并将其分解。

你对其他socket使用socket写入函数。当您添加EOF char时,它仅用于其他套接字recv。但是,您必须知道为recv编写的套接字的EOF char,并将其分解。

让我们尝试添加一个长度头,因为当涉及字符串时,这是最安全的方法

您的客户机需要发送该信息,因此需要对原始代码稍作更改:$msg=strlen$msg$味精;就在$msg=json_encode[msg=>$arr[rand0,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";
    }
}

让我们尝试添加一个长度标题,因为当涉及字符串时,这是最安全的方法

您的客户机需要发送该信息,因此需要对原始代码稍作更改:$msg=strlen$msg$味精;就在$msg=json_encode[msg=>$arr[rand0,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";
    }
}

一些人在消息前面加上长度,另一些人在消息前面加上终止字符,另一些人两者都加。我认为终止字符策略不适合JSON。传递类似于11{msg:I}的内容,然后获取另一侧的数字,并将字符推入固定长度数组中,直到其满为止。然后将其解码并继续下一个数字。另外,在添加特殊字符时尝试使用单引号,以免被解释。@nevvermind喜欢先读取11,然后读取11个字符和下一个数字,依此类推?@nevvermind您还可以解释一下最后一个字符串的情况吗?我的意思是,当缓冲区中没有空间时,它不会被切断吗?我可能会得到部分json对象?您发送的每个json文本都会在前面加上其长度。这也包括最后一个,不是吗?这样你就可以事先知道你期望的长度。看看这些。一种是处理您的具体情况,虽然没有告诉您具体的情况,但是要处理格式。一些是用消息长度作为消息的前缀,另一些是用终止字符作为消息的前缀,另一些则两者兼而有之。我认为终止字符策略不适合JSON。传递类似于11{msg:I}的内容,然后获取另一侧的数字,并将字符推入固定长度数组中,直到其满为止。然后将其解码并继续下一个数字。另外,在添加特殊字符时尝试使用单引号,以免被解释。@nevvermind喜欢先读取11,然后读取11个字符和下一个数字,依此类推?@nevvermind您还可以解释一下最后一个字符串的情况吗?我的意思是,当缓冲区中没有空间时,它不会被切断吗?我可能会得到部分json对象?您发送的每个json文本都会在前面加上其长度。这也包括最后一个,不是吗?这样你就可以事先知道你期望的长度。看看这些。其中一个处理的是您的具体情况,虽然没有告诉您具体情况,但是格式;但这是可怕的和更好的。ThanksI读取整个字符串并使用preg_match和substr完成相同的操作;但这是可怕的和更好的。谢谢
$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";
    }
}