在线:为什么接收到的数据与发出去的不符,而且还出现内存访问错误(使用TSeverSocket与TClientSocket)

amdcwf 2003-08-31 11:08:37
定义如下数据结构:

type Block=record

Num:integer;//块在块列表的序号
ScrRect:iScrRect;//对应的屏幕矩形
UserName:string;//计算此块的计算机名
UserIP:string;//计算此块的计算机IP
UserSocketID:integer;//计算此块的Socket连接句柄
DispatchedTime:string;//被分配出去的时间
CompletetTime:string;//计算完成的时间
end;
type CalPara=record//定义发送给Client端的计算参数的消息数据结构
cMin:ePoint;
sDCX:extended; //复数实部变化步长
sDCY:extended;//复数虚部变化步长
iMaxLoopNum:integer;//最大迭代次数
iBoarder:extended; //吸引子
end;
type AllCalInfo=record
BlockInfo:Block;
CurCalPara:CalPara;
end;

发送端:
function getAllCalInfo(var ACI:AllCalInfo):boolean;

begin
if BlockNum<>-1 then
begin

ACI.BlockInfo:=Blocks[BlockNum];

ACI.CurCalPara.cMin.X:=StrToFloat(FrmServer.LedtcXMin.Text);
ACI.CurCalPara.cMin.Y:=StrToFloat(FrmServer.LedtcYMin.Text);

ACI.CurCalPara.sDCX:=

(strToFloat(FrmServer.LedtcXMax.Text)-StrToFloat(FrmServer.LedtcXMin.Text))/FrmServer.SpWidth.Value;
ACI.CurCalPara.sDCY:=
(StrToFloat(FrmServer.LedtcYMax.Text)-StrToFloat(FrmServer.LedtcYMin.Text))/FrmServer.SpHeight.Value;
ACI.CurCalPara.iMaxLoopNum:=FrmServer.SpNum.Value;
ACI.CurCalPara.iBoarder:=FrmServer.SpXYZ.Value;
result:=true;
end else result:=false;

end;

var Info:^AllCalInfo;

begin
GetMem(Info,SizeOf(blocks[0]));
if getAllCalInfo(Info^) then
begin

SendNum:=Socket.SendBuf(Info,sizeOf(AllCalInfo));


end else showmessage('发生意外,不能取得计算信息!')

end;

Client端:

var
re:pchar;
CalInfo:^AllCalInfo;
sbuf:string;
relong:integer;

begin



// ShowMessage(inttostr(Sizeof(AllCalInfo)));

reLong:=Socket.ReceiveLength;
GetMem(CalInfo,reLong);


ZeroMemory(CalInfo,reLong);
Socket.ReceiveBuf(CalInfo,reLong);

if CalInfo^.BlockInfo.Num >-1 then//在这里查看CalInfo^的数据,发现与发送的不同
begin
Echo.Lines.Add('得到任务...');
end;
end;
end;
在线等待!!!
...全文
55 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
amdcwf 2003-09-06
  • 打赏
  • 举报
回复
这么说,我必须在程序中添加检查是否收到完整数据的控制程序?
redmu 2003-09-06
  • 打赏
  • 举报
回复
没有必要想得太麻烦,需要解决的是两件事,
第一:
----reLong:=Socket.ReceiveLength;-----
relong得到的是socket包当前的尺寸,而不是你发送数据的尺寸(前提:你发的socket包的尺寸小于
你的希望发的数据的尺寸,因为socket打包时有固定尺寸,参照<socket规范>)

解决:发送数据前首先发送收据的尺寸 //datasize

第二:
server端受到尺寸后,开一同样尺寸的memory,开始copy得到的数据,然后计算memory.size是否
和datasize相等,相等,继续其他操作,不等,不进行任何操作,因为onclientread事件会被发来的
socket包持续激发,直至memory.size与datasize相等为止

这种方法适用于任何TmemoryStream的发送,速度也可以,完全取决于网络速度和主机配置了,发送时
一次性发送所有需要发送的数据,不要限定尺寸发送,socket会帮你计算,接受同样不限定,只需计算
datasize和memory.size是否相等就好了,发送和接受之间就不用再写什么协议了
zjqyb 2003-09-03
  • 打赏
  • 举报
回复
SendNum:=Socket.SendBuf(Info^,sizeOf(AllCalInfo));


Socket.ReceiveBuf(CalInfo^,reLong);
XXSingle 2003-09-03
  • 打赏
  • 举报
回复
发送,接收最终得到的数据应该相等,除网络问题外
power_yhb 2003-09-03
  • 打赏
  • 举报
回复
发送和接收一定是相等的,
因为SOCKET是传送不会丢失数据.但是你要明白,不是你发出多少数据,对方就能一次性收到数据.有可能要分多个包.如5K的数据,系统可能分成2个包发送.这完全是因为网络问题.
amdcwf 2003-09-03
  • 打赏
  • 举报
回复
没人回答,太失望了

1,593

社区成员

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

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