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

  • 主题发起人 主题发起人 amdcwf
  • 开始时间 开始时间
A

amdcwf

Unregistered / Unconfirmed
GUEST, unregistred user!
定义如下数据结构:

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;
在线等待!!!
 
用來發送記錄中的域必須是定長的,顯然,你定義的記錄中string類型是不定長的.
所以必須改為類似UserName:string[20]的結構.
另外,此處記錄類型最好加上packed.
type Block=packed record
Num:integer;//块在块列表的序号
ScrRect:iScrRect;//对应的屏幕矩形
UserName:string[20];//计算此块的计算机名
UserIP:string[15];//计算此块的计算机IP
UserSocketID:integer;//计算此块的Socket连接句柄
DispatchedTime:string[20];//被分配出去的时间
CompletetTime:string[20];//计算完成的时间
end;
 
赞成 smokingroom 的看法,把BLOCK变成定长,再用STREAM传送就可以了.
 
我按smokingroom的方法还是不行
另外能告诉我packed的意思吗
还有如何按aleyn说的用stream方法来传(为什么非得用stream呢)
 
//Socket.SendBuf(var Buf; Count: Integer): Integer;
SendNum:=Socket.SendBuf(Info^,sizeOf(AllCalInfo));
Socket.ReceiveBuf(CalInfo^,reLong);
packed的问题见 ID=1015017
 
packed的问题见 ID=1015017?????
怎么找?
 
http://www.delphibbs.com/delphibbs/dispq.asp?LID=1015017
看 Pipi. 大侠的见解
 
我想问一下
type CalPara=record//定义发送给Client端的计算参数的消息数据结构
cMin:ePoint;
sDCX:extended; //复数实部变化步长
sDCY:extended;//复数虚部变化步长
iMaxLoopNum:integer;//最大迭代次数
iBoarder:extended; //吸引子
end;
这个数据结构中的各个存储各个数据类型的址是连续的吗?


 
我想补弃一下:就是我发出了的内容大小与收到的大小是一样的
可就是里面的值都不对
而且有时系统还报错说使用了什么特权指令,云云,真是搞不懂了
 
用不用Stream無所謂,首先你必須將記錄桔構中的字符串域的長度定好.
其次,發送出與接收時對指針的操作有誤.建議你不要用指針,因為我覺得你這里沒有這個必要.
var Info: AllCalInfo;
begin
if getAllCalInfo(Info) then
SendNum:=Socket.SendBuf(Info,sizeOf(AllCalInfo));
else
showmessage('发生意外,不能取得计算信息!')
end;

var
CalInfo:AllCalInfo;
sbuf:string;
relong:integer;
begin
reLong:=Socket.ReceiveLength;
Socket.ReceiveBuf(CalInfo,reLong);
if CalInfo.BlockInfo.Num >-1 then//在这里查看CalInfo的数据,发现与发送的不同
begin
Echo.Lines.Add('得到任务...');
end;
end;


 
感谢smokingroom,不过不明白为什么用指针就不行呢?(以后自己去看看了)
 
多人接受答案了。
 
后退
顶部