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

时间:2021-08-02 23:55:01

        这几天遇到的比较麻烦的问题,用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)。乱码中除了不正常显示的符号外,不认识的字符也是汉字的,不要以为那就是乱码,只是不常见汉字而已,这种情况下判断单双字节决定是否为汉字是有问题的。