T
terrace
Unregistered / Unconfirmed
GUEST, unregistred user!
我在Delphi 5下基于TCP/IP用ClientSocket和ServerSocket进行非阻塞通信,客户端发出数据请求,服务器接到请求后在库里查询记录并返回(一条记录为一包,大小在140个字节左右,通常为几千个包,服务器端已经固定,我无法修改,只能修改客户端),但我的客户端接收到的数据与我所期望的并不一致(表现为不稳定,有时处理成功有时失败),不知道究竟是服务器发包不对还是我的处理代码有问题,请大虾们帮我看看如下的代码:
type
TPackHeader =packed record
len : longint; //包的总长度,为包头和包体长度总和
morepkt : char; //1:有后续包 0:无
sequence : longint; //包序号
errorcode : smallint; //返回码
end;
type
TPackage=packed record
PackHeader : TPackHeader; //包头
datatrans : array[0..0] of char; //传送内容,从datatrans开始, end; //实际使用时取其地址作为指针使用
TPPackage=^TPackage;
const PackHeadSize=11;
var
ErrorInfo:string;
templist:TStringList;
procedure Tfrm_Progress.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
DataTrans:array[0..2048-1] of char;
Data:string;
PackHeader:TPackHeader;
tempSize:integer;
BodySize:integer;
Pointer;
RecLen:Integer;
begin
while true do //去掉while循环还是有问题
begin
if socket.ReceiveLength<=PackHeadSize then continue;//去掉该句还是有问题
fillchar(PackHeader,sizeof(PackHeader),#0);
tempSize:=0;
while tempSize<PackHeadSize do
begin
P:=pointer(integer(@PackHeader)+tempSize);
RecLen:=socket.ReceiveBuf(p^,PackHeadSize-tempSize);
if RecLen>0 then
tempSize:=tempSize+RecLen
else
delay4(0,0,0,1);
end;
DataTrans:=#0;
BodySize:=PackHeader.len-PackHeadSize;
tempSize:=0;
while tempSize<BodySize do
begin
RecLen:=socket.ReceiveBuf(DataTrans[tempSize],BodySize-tempSize);
if RecLen > 0 then
tempSize:=tempSize+RecLen
else
delay4(0,0,0,1);
end;
Data:=copy(PChar(@DataTrans),0,PackHeader.len-PackHeadSize);
//DataTrans数组中的有效数据无#0,最后一个字符才为#0,故copy该句应该没问题
if PackHeader.errorcode<>0 then //如果查询出错
begin
ErrorInfo:='Error!'; //有时程序从这里退出,说明接到的包数据乱了,??
Exit;
end;
templist.Add(Data);
if (PackHeader.morepkt = '0') then
begin
ErrorInfo:='Complete!';
ProcessData();//数据包全部接收完,开始进行处理,提取各字段写入数据库操作
exit;
end;
end;
//延时函数
procedure Tfrm_Progress.Delay4(Hour,Min,Sec,MSec:word);
var timeout:TDateTime;
begin
timeout:=now+encodeTime(Hour,Min,Sec,MSec);
While now<timeout do
Application.ProcessMessages;
end;
分全给了,请高手指点是否代码可行?如果不,请给出一个类似处理的例子(有服务器端代码更好),另外,有什么办法可以一边接收一边ProcessData()处理数据而保证不会出错?很急很急,万万分感谢!!!我的邮箱:quietosea@163.com
type
TPackHeader =packed record
len : longint; //包的总长度,为包头和包体长度总和
morepkt : char; //1:有后续包 0:无
sequence : longint; //包序号
errorcode : smallint; //返回码
end;
type
TPackage=packed record
PackHeader : TPackHeader; //包头
datatrans : array[0..0] of char; //传送内容,从datatrans开始, end; //实际使用时取其地址作为指针使用
TPPackage=^TPackage;
const PackHeadSize=11;
var
ErrorInfo:string;
templist:TStringList;
procedure Tfrm_Progress.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
DataTrans:array[0..2048-1] of char;
Data:string;
PackHeader:TPackHeader;
tempSize:integer;
BodySize:integer;
Pointer;
RecLen:Integer;
begin
while true do //去掉while循环还是有问题
begin
if socket.ReceiveLength<=PackHeadSize then continue;//去掉该句还是有问题
fillchar(PackHeader,sizeof(PackHeader),#0);
tempSize:=0;
while tempSize<PackHeadSize do
begin
P:=pointer(integer(@PackHeader)+tempSize);
RecLen:=socket.ReceiveBuf(p^,PackHeadSize-tempSize);
if RecLen>0 then
tempSize:=tempSize+RecLen
else
delay4(0,0,0,1);
end;
DataTrans:=#0;
BodySize:=PackHeader.len-PackHeadSize;
tempSize:=0;
while tempSize<BodySize do
begin
RecLen:=socket.ReceiveBuf(DataTrans[tempSize],BodySize-tempSize);
if RecLen > 0 then
tempSize:=tempSize+RecLen
else
delay4(0,0,0,1);
end;
Data:=copy(PChar(@DataTrans),0,PackHeader.len-PackHeadSize);
//DataTrans数组中的有效数据无#0,最后一个字符才为#0,故copy该句应该没问题
if PackHeader.errorcode<>0 then //如果查询出错
begin
ErrorInfo:='Error!'; //有时程序从这里退出,说明接到的包数据乱了,??
Exit;
end;
templist.Add(Data);
if (PackHeader.morepkt = '0') then
begin
ErrorInfo:='Complete!';
ProcessData();//数据包全部接收完,开始进行处理,提取各字段写入数据库操作
exit;
end;
end;
//延时函数
procedure Tfrm_Progress.Delay4(Hour,Min,Sec,MSec:word);
var timeout:TDateTime;
begin
timeout:=now+encodeTime(Hour,Min,Sec,MSec);
While now<timeout do
Application.ProcessMessages;
end;
分全给了,请高手指点是否代码可行?如果不,请给出一个类似处理的例子(有服务器端代码更好),另外,有什么办法可以一边接收一边ProcessData()处理数据而保证不会出错?很急很急,万万分感谢!!!我的邮箱:quietosea@163.com