服务端用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试验了一下,就一切正常,说明是发送内容上的问题,请教高手指点。
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试验了一下,就一切正常,说明是发送内容上的问题,请教高手指点。
解决方案 »
- 如何把一个pascal string 拷贝到一个array[0...19] of char中去?
- 怎么让游戏窗口化启动运行 比如天骄、天堂等 感谢
- 200分解决问题,三层结构中,有些记录删除不掉,再次删除,还有些记录删除不掉,多次之后才删除掉。
- 请教如何定义一棵树的结构?或者构造的算法?
- 如何在 dbgrid 和 stringGrid 中实现不,当按完回车键,焦点移到下一格或右边的一格。
- 有关操作符"and"的使用,请高手指点!
- 急:如何得到grid选中的行数,然后得到这一行某一列上的值呢?
- delphi的优点?
- QuickRepeat批量打印问题
- 奇怪啊!query控件中的sql语句的问题?
- 为什么我D7装fastreport3的后 在控件里面没有DBDATASET呢急啊!在线等!
- 瑞友天翼 那位大哥用过 觉得怎么样?
动态数组最好用setlength(a,100), 释放setlength(a,0);
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 的大小呢?
动态数组最好用setlength(a,100), 释放setlength(a,0); a:=nil;
new(TSocket_Rec);
.......
setlength(TSocket_Rec.Msg,0); TSocket_Rec.Msg:=nil;
dispose(TSocket_Rec);
Socket_Rec = packed record
MsgType: String[2]; {命令字}
MsgLen: Word; {协议体长度}
Msg: array of Byte; {协议内容}
end;
1. SizeOf(MsgType)、SizeOf(Msg)、SizeOf(Sockt_Rec)分别都是多少?
答案是3、4、92.
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
Msg: record end;
{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;就好了,谢谢各位