socket传输汉字截断为乱码问题的解决

本文介绍了一种在Delphi客户端通过Socket接收由Java服务器发送的大数据量时,如何处理因数据包大小限制导致的汉字截断问题。通过判断汉字的字节类型并进行正确的组合,解决了由此产生的乱码问题。

        这几天遇到的比较麻烦的问题,用delphi的socket控件传输数据,服务器端是java发送,客户端是delphi接收,数据量也比较大,其中有字符、汉字、数字,大部分情况下接收到的数据显示正常,但有时会出现乱码,经过观察发现,由于数据包大小的限制,发送的数据有可能把汉字截断,只发送第一个字节过来,而第二个字节在下一批包里发送。这样,接收的第一个包里的数据进行解析时,不能正确识别最后的字节,出现‘?’和黑方块。接收到的第二个包里解析的字符串头几个字符也是乱码:因为把截断汉字的第二个字节与后面的字节拼凑了。经过多方查阅与实验,终于搞定。

       为了更清晰的说明,先定义几个变量:vLen:接收字符串的长度;bufByte[1..2]保存拆开字节的数据;reStr:接收的字符串;addStr:string存放拼凑的汉字;

       思路:首先判断接收包的最后一个字节是不是汉字的字节,函数为:ByteType(string;integer),返回值为mbSingleByte:为单字节——数字或字符;mbLeadByte:汉字的第一个字节;mbTrialByte:汉字的第二个字节。我们要用的就是判断最后一个字节是否为mbTrialByte,如果是,恭喜:汉字被截断了!然后用一个Byte[1]保存这个字节,bufByte[1]=Byte(reStr[vlen]);然后reStr:=Copy(reStr,1,vlen-1)。再取下一个包的第一个字节,此时reStr已经是第二批接收的字符串了。把它存在bufByte[2]中,bufByte[2]:=Byte(reStr[1]),然后将两个字节拼凑起来转换为汉字:setString(addStr,pchar(@bufByte[1],2)。把addStr加到reStr的前面,reStr:=addStr+Copy(reStr,2,vlen)。如此循环,这样,就可以把因为截断造成的乱码汉字组合进第二批字符串里正常显示了。 

       一点小知识:传输中,一个汉字为两个字节,字符和数字都为一个字节,汉字的两个字节的大小都大于0xa0(十进制160)。乱码中除了不正常显示的符号外,不认识的字符也是汉字的,不要以为那就是乱码,只是不常见汉字而已,这种情况下判断单双字节决定是否为汉字是有问题的。

import socket import json import struct import time import random def send_realtime_data_via_socket(server_host='127.0.0.1', server_port=12345): """ 将实时数据转换为JSON格式并通过Socket发送。 参数: server_host: 服务器IP地址(默认本地) server_port: 服务器端口号 """ # 创建Socket连接 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client_socket.connect((server_host, server_port)) print(f"已连接到服务器 {server_host}:{server_port}") # 模拟实时数据发送(每秒1次) while True: # 1. 生成实时数据(示例:传感器数据) realtime_data = { "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), "temperature": round(random.uniform(20.0, 30.0), 2), # 随机温度值 "humidity": round(random.uniform(40.0, 80.0), 2), # 随机湿度值 "device_id": "sensor_001" } # 2. 转换为JSON字符串 json_data = json.dumps(realtime_data, ensure_ascii=False) # ensure_ascii=False支持中文 print(f"生成JSON数据: {json_data}") # 3. 添加报头:先打数据长度(4字节) header = struct.pack('I', len(json_data)) # 'I'表示4字节无符号整数 # 4. 将JSON字符串编码为bytes body = json_data.encode('utf-8') # 5. 发送数据:报头 + 主体 client_socket.sendall(header + body) print("数据发送成功!") # 等待1秒,模拟实时性 time.sleep(1) except Exception as e: print(f"传输错误: {e}") finally: client_socket.close() print("连接已关闭") # 测试运行(需先启动服务器) if __name__ == "__main__": send_realtime_data_via_socket()我发送时将数据humidity改成中文,发不出去了怎么改
最新发布
08-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值