热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Socket服务器程序接收中文数据时出现乱码问题分析及解决方案,客户端使用C#编写,返回中文数据可正常显示

在分析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 个解决方案

#1


p: string;

GetMem(p, lh);改为:setlength(p,lh);
    try
      Socket.ReceiveBuf(p[0], Socket.ReceiveLength);

#2


不好使呀,又错误
Socket.ReceiveBuf(p[0], Socket.ReceiveLength);//这句又错误

#3


看一下这篇文章是否对你有帮助:
http://www.csdn.net/develop/article/19/19977.shtm

#4


Socket.ReceiveBuf(p[0], Socket.ReceiveLength);改为Socket.ReceiveBuf(p, Socket.ReceiveLength);

#5


呵呵,上面错了,这样更简单:

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;

#6


不要用不可靠的ReceiveLength.

缓冲区分配一个定长就行了.

#7


我的想法:
如果你的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结尾的。

推荐阅读
  • 本文详细介绍了中心方形数的概念及其计算方法,并提供了多种编程语言下的实现代码。 ... [详细]
  • 一个产品数组拼图|集合 2 (O(1)空间) ... [详细]
  • 本文章介绍了如何将阿拉伯数字形式的金额转换为中国传统的大写形式,适用于财务报告和正式文件中的金额表示。 ... [详细]
  • 设计模式笔记12:迭代器模式(Iterator Pattern) ... [详细]
  • 程序打印菱形 ... [详细]
  • 本文介绍如何利用JavaScript在页面加载时为ASP.NET的DropDownList控件设置特定的选项值。 ... [详细]
  • jme-燃烧的火焰
    jme的粒子效果也让人炫目:publicclassHelloParticleextendsSimpleApplication{publicstaticvoid ... [详细]
  • 本文通过SystemTap工具详细分析了lvextend命令在SUSE12sp3系统上的执行流程。首先介绍了必要的软件安装步骤,随后展示了如何编写并运行SystemTap脚本来追踪命令执行过程中的函数调用,最后结合实际输出结果对关键函数进行了深入分析。 ... [详细]
  • 线程是创建并发的底层工具,因此具有一定的局限性。没有简单的方法可以从联合(Join)线程得到“返回值”。因此必须创建一些共享域。当抛出一个异常时,捕捉和处理异常也是麻烦的。线程完成之后,无法再次启动该 ... [详细]
  • 右下角动态通知实现
    本文介绍如何在网页中实现右下角滑动通知的功能,包括前后台代码示例及具体实现步骤。 ... [详细]
  • 深入解析Java设计模式之责任链模式
    责任链模式通过将处理请求的对象链接成一条链,确保每个请求能够沿着这条链传递,直至找到合适的处理者。本文将详细介绍责任链模式的原理、优势、局限及实际应用案例。 ... [详细]
  • 本文档详细介绍了如何利用 HTMLUnit 进行 Web 页面的自动化测试和数据抓取,包括环境配置、基本用法及高级功能。 ... [详细]
  • 本文详细介绍了Oracle数据库的基本架构,包括数据文件和内存结构的概念。文章重点解释了Oracle实例的组成部分,如系统全局内存区域(SGA)和后台进程,以及客户端进程与服务器进程的交互方式。此外,还探讨了SGA中的共享池、库高速缓存、锁存器及SGA缓冲区缓存等关键组件的功能和运作机制。 ... [详细]
  • python第一天学习python
    1、python语言可使用的开发工具有:charles、fiddles等。。。2、语言分类:编译型和解释型,编译型如:c、c++、c#。。。。解释型:python、java、php ... [详细]
  • 统计字符串中字母个数(C#程序设计)
    C#程序设计:privatevoidbutton1_Click(objectsender,EventArgse){int[ ... [详细]
author-avatar
算错的账目
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有