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

时间:2015-03-21 00:43:13

标签: 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($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”来告诉服务器端流,但它不起作用。请帮帮我的朋友。提前谢谢!

2 个答案:

答案 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字符并将其爆炸。