作者:算错的账目 | 来源:互联网 | 2024-11-05 14:21
在分析Socket服务器程序接收中文数据时出现的乱码问题时,我们发现客户端使用C#编写的数据在返回时能够正常显示。本文详细探讨了该问题的成因,并提出了一种有效的解决方案。通过调整字符编码设置和优化数据传输格式,确保了中文数据在传输过程中的完整性与正确性。具体实现代码包括对Socket读取事件的处理,确保数据以正确的编码格式进行解析和显示。
代码如下:
procedure TFrm_Main.SSClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
p: pchar;
lh: longint;
Count, i: integer;
ReceStr: string;
begin
//p := nil;
while Socket.ReceiveLength > 0 do
begin
lh := Socket.ReceiveLength;
GetMem(p, lh);
try
Socket.ReceiveBuf(p^, Socket.ReceiveLength);
ReceStr := StrPas(p);
Memo_Log.Lines.Add(ReceStr); //memo上显示的是乱码
Count := SS.Socket.ActiveConnections;
for i := 0 to Count - 1 do
begin
SS.Socket.Connections[i].SendBuf(p^, lh);//发出的数据在C#的窗体上 可以正常显示
end;
finally
FreeMem(p);
end;
end;
end;
//s是不是PChar类型的问题呀??
谢谢了
7 个解决方案
p: string;
GetMem(p, lh);改为:setlength(p,lh);
try
Socket.ReceiveBuf(p[0], Socket.ReceiveLength);
不好使呀,又错误
Socket.ReceiveBuf(p[0], Socket.ReceiveLength);//这句又错误
看一下这篇文章是否对你有帮助:
http://www.csdn.net/develop/article/19/19977.shtm
Socket.ReceiveBuf(p[0], Socket.ReceiveLength);改为Socket.ReceiveBuf(p, Socket.ReceiveLength);
呵呵,上面错了,这样更简单:
procedure TFrm_Main.SSClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Count, i: integer;
begin
//p := nil;
while Socket.ReceiveLength > 0 do
begin
Memo_Log.Lines.Add(Socket.ReceiveText);
Count := SS.Socket.ActiveConnections;
for i := 0 to Count - 1 do
begin
SS.Socket.Connections[i].SendBuf(Memo_Log.Lines[Memo_Log.Lines.Count-1], length(Memo_Log.Lines[Memo_Log.Lines.Count-1]));
end;
end;
end;
不要用不可靠的ReceiveLength.
缓冲区分配一个定长就行了.
我的想法:
如果你的TClientSocket的ClientType是非阻塞式的(ctNonBlocking),
那么就用Socket.ReceiveText接收文本信息,比用Socket.ReceiveBuf安全一些。
同样发送文本信息用Socket.SendText而不是Socket.SendBuf
为什么使用ReceiveBuf接收文本信息不安全?
- ReceiveLength返回的值不是精确的
- GetMem(p, lh);使用GetMem为p分配的内存并没有初始化(以0填充),而PChar是以0结尾的,StrPas转化时有可能出现越界(超过p的实际范围)而产生乱码。
如果必须使用ReceiveBuf接收文本信息建议用AllocMem代替GetMem,同时保证为p分配的内存大于实际需要的大小,以保证接收到的文本是以0结尾的。