You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP TCP Socket监听GPS追踪器:后续接收数据乱码问题求助

GPS追踪器TCP数据后续接收乱码问题

我用PHP编写了TCP服务器,GPS追踪器每5秒通过TCP发送一次数据。当前问题:Socket与客户端建立连接后,首次接收的数据正常,但后续接收的数据全是乱码,无法解析。

服务器代码(Server.php)

<?php

require_once("SocketServer.class.php"); 
$server = new SocketServer("172.xx.xx.xxx",8000); 
$server->max_clients = 10; 
$server->hook("CONNECT","handle_connect"); // 客户端连接时触发handle_connect
$server->hook("INPUT","handle_input"); 
$server->infinite_loop(); 


function handle_connect(&$server,&$client,$input) {
    SocketServer::socket_write_smart($client->socket,"String? ","");
}


function handle_input(&$server,&$client,$input) {
  
    $trim = trim($input); 

    if(strtolower($trim) == "quit") 
    {
        SocketServer::socket_write_smart($client->socket,"Oh... Goodbye..."); 
        $server->disconnect($client->server_clients_index); // 断开该客户端连接
        return; 
    }

    $output = strrev($trim); 

    SocketServer::socket_write_smart($client->socket,$output); 
    SocketServer::socket_write_smart($client->socket,"String? ",""); 
}

服务器输出

Triggering Hook 'handle_connect' for 'CONNECT'
*HQ,9176952312,V6,115939,V,3127.2665,N,07307.6974,E,0.00,126.00,100822,FFF7FBFF,410,1,325,14688,8992300001243970980F,#

Triggering Hook 'handle_input' for 'INPUT'
0@119.160.59.240 --> $?v?#uY"1'&e0v?
                                    &????ʧ?E9`,
Triggering Hook 'handle_input' for 'INPUT'
0@119.160.59.240 --> $?v?#uY"1'&e0v?
                                    &????ʧ?E9`,

数据十六进制Dump

正常数据(首次接收)

<Buffer 2a 48 51 2c 39 31 37 36 39 35 32 33 37 35 2c 56 36 2c 31 35 35 37 32 32 2c 56 2c 33 31 32 37 2e 33 30 33 34 2c 4e 2c 37 33 30 37 2e 36 36 33 36 2c 45 ... 65 more bytes>

异常数据(后续接收)

24 91 76 95 23 75 15 57 24 10 08 22 31 27 30 34 04 07 30 76 63 0c 00 00 00 ff f7 fb ff 00 01 c7 f0 00 00 00 00 01 9a 01 01 45 7f 2d 00

问题原因及解决方案

核心问题分析

  1. TCP粘包/拆包:TCP是流式协议,当前使用的SocketServer.class.php未正确处理数据边界,首次接收的是完整数据包,但后续将多个包的内容混读,或只读取了部分包,导致解析乱码。
  2. 二进制数据被文本函数破坏:GPS设备发送的可能是二进制格式数据,代码中用trim()、strrev()等文本处理函数直接操作,会破坏二进制结构(比如遇到空字节0x00时会截断数据),后续处理自然出错。
  3. 无关响应干扰设备:服务器回写的反转字符串和String? 并非GPS设备期望的响应,可能导致设备切换发送模式(比如从文本协议转为二进制协议),进而出现乱码。

具体修复步骤

1. 处理数据边界,解决粘包/拆包

GPS协议通常有明确结束符(比如首次数据中的#),修改handle_input函数,缓存客户端输入,直到读取到完整数据包再处理:

function handle_input(&$server,&$client,$input) {
    // 给客户端对象添加缓存,存储未处理的部分数据
    if (!isset($client->buffer)) {
        $client->buffer = '';
    }
    $client->buffer .= $input;

    // 按协议结束符分割完整数据包(这里假设结束符是#)
    while (($pos = strpos($client->buffer, '#')) !== false) {
        $full_data = substr($client->buffer, 0, $pos + 1); // 取出包含结束符的完整包
        $client->buffer = substr($client->buffer, $pos + 1); // 剩余数据留到下次处理

        // 在这里处理完整的$full_data
        var_dump("完整数据包:", $full_data);
    }

    // 移除无关回写,避免干扰设备
    // SocketServer::socket_write_smart($client->socket,$output); 
    // SocketServer::socket_write_smart($client->socket,"String? ",""); 
}

2. 避免用文本函数处理二进制数据

不要用trim()、strrev()这类针对文本的函数操作GPS二进制数据,直接对原始字节流处理;如果是文本协议,也要确保仅在拿到完整包后再做字符串操作。

3. 检查SocketServer类的读取逻辑

查看SocketServer.class.php中socket_read的调用逻辑,确保没有限制单次读取字节数过小,或未处理不完整数据包的情况。

4. 停止向设备发送无关响应

GPS追踪器不需要String? 这类文本响应,直接删除handle_connect和handle_input中的回写代码,避免设备切换发送模式。

内容的提问来源于stack exchange,提问作者coderdeveloperprogrammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 23:54:06