请问关于收发带Byte数组的结构

lezerger 2009-04-22 04:47:54
服务端用TServerSocket,客户端用TTcpClient。

结构体在客户端和服务端都是这样定义的:

{Socket通讯结构体}
Socket_Rec = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: array of Byte; {协议内容}
end;
{定义指针}
TSocket_Rec = ^Socket_Rec;

{实际要传输的数据}
RefreshLink_Rec = packed record
TheType : Integer;
ClientIP : string[15];
end;


服务端:

var
Info: Socket_Rec;
bodyInfo, bodyInfoRep: RefreshLink_Rec;
LastTest: TSocket_Rec;

....

procedure TForm1.ServerSocketMainClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
BufferLen,Len: Integer;
begin
BufferLen := Socket.ReceiveLength;
{接受}
Socket.ReceiveBuf(Info,BufferLen);
Move(Info.Msg,bodyInfo,Info.MsgLen);{只是接受,接受到的数据另做它用,这里就不写了}

{组织发送数据}
bodyInfoRep.TheType := 2;
bodyInfoRep.ClientIP := '192.168.2.2';

{发送}
Len := SizeOf(Socket_Rec)-1+SizeOf(bodyInfoRep);
GetMem(LastTest,Len);
LastTest.MsgType := 'BA';
LastTest.MsgLen := SizeOf(bodyInfoRep);
Move(bodyInfoRep,LastTest.Msg,SizeOf(bodyInfoRep));
Socket.SendBuf(LastTest^,Len);
FreeMem(LastTest);




客户端:

var
Info: Socket_Rec;
bodyInfo, bodyInfoRep: RefreshLink_Rec;
LastTest: TSocket_Rec;

....
procedure TForm1.btn1Click(Sender: TObject);
var
Len: Integer;
chr: array[0..9]of Char;
begin
if not ClientSocket1.Active then
begin
ClientSocket1.RemoteHost := '192.168.0.136';
ClientSocket1.RemotePort := '1013';
ClientSocket1.Active := True;
end;

{组织发送数据}
bodyInfo.TheType := 1;
bodyInfo.ClientIP := '192.168.0.136';

{发送}
GetMem(LastTest,SizeOf(Socket_Rec)-1+SizeOf(bodyInfo));
LastTest.MsgType := 'AA';
LastTest.MsgLen := SizeOf(bodyInfo);
Move(bodyinfo,LastTest.Msg,SizeOf(bodyInfo));
ClientSocket1.SendBuf(LastTest^,SizeOf(Socket_Rec)-1+SizeOf(bodyInfo));
FreeMem(LastTest);

{接收}
ClientSocket1.ReceiveBuf(Info,100);
Move(Info.Msg,bodyInfoRep,Info.MsgLen);
memo1.line.add(bodyInfoRep.ClientIP);
end;



客户端发送和接受都没有问题,但就是客户端程序关闭的时候报内存错误。
我把ReceiveBuf和SendBuf的内容改成array[0..10]of char试验了一下,就一切正常,说明是发送内容上的问题,请教高手指点。
...全文
108 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lezerger 2009-04-23
  • 打赏
  • 举报
回复
解决了,Seamour兄说的在理,我把
  
{Socket通讯结构体}
Socket_Rec = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: array of Byte; {协议内容}
end;

改成
  
{Socket通讯结构体}
Socket_Rec = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: array [0..0] of Byte; {协议内容}
end;

就好了,谢谢各位
Bear_hx 2009-04-22
  • 打赏
  • 举报
回复
是不是字符数组没有赋\0
Bear_hx 2009-04-22
  • 打赏
  • 举报
回复
楼主代码风格非常好,赞一个
Seamour 2009-04-22
  • 打赏
  • 举报
回复
刚才Socket_Rec2中的Msg手误写错了,应该是
Msg: record end;
Seamour 2009-04-22
  • 打赏
  • 举报
回复
这代码……先问你几个问题
Socket_Rec = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: array of Byte; {协议内容}
end;
1. SizeOf(MsgType)、SizeOf(Msg)、SizeOf(Sockt_Rec)分别都是多少?
答案是3、4、9

2.
var foo: Socket_Rec;
begin
SetLeng(foo.Msg, 100);
end;
现在假设 @foo 的地址是 $00123400,你认为通过上面的代码能知道 @foo.Msg[0] 的地址是多少么?如果可以知道的话,应该是多少?

在你的代码中,出错的原因是在清理 Socket_Rec 结构的时候,rtl 企图自动释放 Msg 占用的内存,但是它的内容早就不知道是什么东西了,而不是一个正确的 array of Byte ,释放一个野指针当然很容易出错了
有两种办法声明你的Socket_Rec,可以让你容易获得Msg的地址,同时不会产生多余的问题:

Socket_Rec1 = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: array[0..0] of Byte; {协议内容}
end;
{ or }
Socket_Rec2 = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: end of record; {协议内容}
end;

SizeOf(Socket_Rec1)、SizeOf(Socket_Rec2)分别是6、5
lezerger 2009-04-22
  • 打赏
  • 举报
回复
array of Byte并没有通过setlength去分配大小,而是直接GetMem分配一块内存,然后把结构给Move进去
lezerger 2009-04-22
  • 打赏
  • 举报
回复
LastTest.Msg实际上是个保存了bodyInfo结构的Byte数组啊,它的大小就是SizeOf(bodyInfo)
jason_28693 2009-04-22
  • 打赏
  • 举报
回复
对了 记录指针 最好 new(p), dispose(p);

静态数组和动态数组内存分配是不一样的,静态数组时内存是连续分配的,而动态则未必!!!
动态数组最好用setlength(a,100), 释放setlength(a,0); a:=nil;
new(TSocket_Rec);
.......
setlength(TSocket_Rec.Msg,0); TSocket_Rec.Msg:=nil;
dispose(TSocket_Rec);
starluck 2009-04-22
  • 打赏
  • 举报
回复


{组织发送数据}
bodyInfo.TheType := 1;
bodyInfo.ClientIP := '192.168.0.136';

{发送}
GetMem(LastTest,SizeOf(Socket_Rec)-1+SizeOf(bodyInfo));
LastTest.MsgType := 'AA';
LastTest.MsgLen := SizeOf(bodyInfo);
Move(bodyinfo,LastTest.Msg,SizeOf(bodyInfo));
ClientSocket1.SendBuf(LastTest^,SizeOf(Socket_Rec)-1+SizeOf(bodyInfo));
FreeMem(LastTest);

LastTest.Msg 的大小呢?


jason_28693 2009-04-22
  • 打赏
  • 举报
回复
静态数组和动态数组内存分配是不一样的,静态数组时内存是连续分配的,而动态则未必!!!
动态数组最好用setlength(a,100), 释放setlength(a,0);
kampan 2009-04-22
  • 打赏
  • 举报
回复
你的 array of Byte; 在哪分配的大小啊?
软件编程规范培训实例与练习 软件编程规范培训实例与练习  问题分类 1 逻辑类问题(A类)-指设计、编码中出现的计算正确性和一致性、程序逻辑控制等方面出现的问题,在系统中起关键作用,将导致软件死机、功能正常实现等严重问题; 接口类问题(B类)-指设计、编码中出现的函数和环境、其他函数、全局/局部变量或数据变量之间的数据/控制传输不匹配的问题,在系统中起重要作用,将导致模块间配合失效等严重问题; 维护类问题(C类)-指设计、编码中出现的对软件系统的维护方便程度造成影响的问题,在系统中不起关键作用,但对系统后期维护造成不便或导致维护费用上升; 可测试性问题(D类)-指设计、编码中因考虑不周而导致后期系统可测试性差的问题。  处罚办法 问题发生率: P=D/S D=DA+0.5DB+0.25DC 其中: P -问题发生率 D -1个季度内错误总数 DA -1个季度内A类错误总数 DB -1个季度内B类错误总数 DC -1个季度内C类错误总数 S -1个季度内收到问题报告单总数 1)当D≥3时,如果P≥3%,将进行警告处理,并予以公告; 2)当D≥5时,如果P≥5%,将进行罚款处理,并予以公告。 目 录 一、逻辑类代码问题 第5页 1、变量/指针在使用前就必须初始化 第5页 【案例1.1.1】 第5页 2、防止指针/数组操作越界 第5页 【案例1.2.1】 第5页 【案例1.2.2】 第6页 【案例1.2.3】 第7页 【案例1.2.4】 第8页 3、避免指针的非法引用 第9页 【案例1.3.1】 第9页 4、变量类型定义错误 第10页 【案例1.4.1】 第10页 5、正确使用逻辑与&&、屏蔽&操作符 第17页 【案例1.5.1】 第17页 6、注意数据类型的匹配 第18页 【案例1.6.1】 第18页 【案例1.6.2】 第18页 7、用于控制条件转移的表达式及取值范围是否书写正确 第20页 【案例1.7.1】 第20页 【案例1.7.2】 第21页 【案例1.7.3】 第22页 8、条件分支处理是否有遗漏 第24页 【案例1.8.1】 第24页 9、引用已释放的资源 第26页 【案例1.9.1】 第26页 10、分配资源是否已正确释放 第28页 【案例1.10.1】 第28页 【案例1.10.2】 第29页 【案例1.10.3】 第30页 【案例1.10.4】 第32页 【案例1.10.5】 第33页 【案例1.10.6】 第35页 【案例1.10.7】 第38页 11、防止资源的重复释放 第39页 【案例1.11.1】 第39页 12、公共资源的互斥性和竞用性 第40页 【案例1.12.1】 第40页 【案例1.12.2】 第40页 二、接口类代码问题 第43页 1、对函数参数进行有效性检查 第43页 【案例2.1.1】 第43页 【案例2.1.2】 第43页 【案例2.1.3】 第44页 【案例2.1.4】 第46页 【案例2.1.5】 第47页 【案例2.1.6】 第48页 2、注意多出口函数的处理 第49页 【案例2.2.1】 第49页 三、维护类代码问题 第51页 1、 统一枚举类型的使用 第51页 【案例3.1.1】 第51页 2、 注释量至少占代码总量的20% 第51页 【案例3.2.1】对XXX产品BAM某版本部分代码注释量的统计 第51页 四、产品兼容性问题 第52页 1、系统配置、命令方式 第52页 【案例4.1.1】 第52页 【案例4.1.2】 第53页 2、设备对接 第54页 【案例4.2.1】 第54页 3、其他 第55页 【案例4.3.1】 第55页 五、版本控制问题 第58页 1、新老代码中同一全局变量不一致 第58页 【案例5.1.1】 第58页 六、可测试性代码问题 第59页 1、调试信息/打印信息的正确性 第59页 【案例6.1.1】 第59页 一、逻辑类代码问题 1、变量/指针在使用前就必须初始化 【案例1.1.1】 C语言中最大的特色就是指针。指针的使用具有很强的技巧性和灵活性,但同时也来了很大的危险性。在XXX的代码中有如下一端对指针的灵活使用: ... ... _UC *puc_card_config_tab; ... ... Get_Config_Table(

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧