Socket通讯中对接收到的数据有时处理成功有时失败,再不解决就下岗了,高手救命呀!!!(10分)

  • 主题发起人 主题发起人 terrace
  • 开始时间 开始时间
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;
P: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
 
我是楼主,刚才漏写了一个与while循环的begin对应的end ,请大家注意!
 
看我的回答
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2103620
 
楼上朋友:
还是不能解决我的问题呀,我已经用了while循环,并且不能等包都接完了才检查包的有效性而应该每接到一个包就检查。能具体说说你的意思吗?拜托了!!!
 
你怎么还不明白?一直接收,直到接到需要的为止不就行了?
 
firstrose朋友:
我是一直接收呀,大的while循环中有两个小whlie循环,第一个while循环一直接收包头,直到包头接完为止,第二个while循环一直接收包体,直到包体接完为止,和你的思想是一致的,能劳驾帮忙看看我贴的代码帮我解决存在的问题吗?谢谢!
 
局网我有源码,公网该如何解决?我也想知道!rlpcdk@163.com
 
出现怎么样的错误?
 
楼上朋友:
我贴出的代码中有如下:
ErrorInfo:='Error!'; //有时程序从这里退出,说明接到的包数据乱了,??
那就是出错的地方。
 
从你代码看,接收过程好象没有问题.估计是server的关系.

这是要c/s两方面配合的.
 
firstrose朋友:
服务器是一条记录(约140个字节)为一个包发送的,会不会因为速度快造成客户端的socket自带的缓冲区被覆盖呢?socket自带的缓冲区大小是多少?可以在程序中自己设置吗?有上限否?谢谢!
 
这个很抱歉,我不知道

不过最好先尽可能收,把收到的数据放到一个缓冲里,再用一个线程分包,处理
 
firstrose朋友:
我一直都很希望能象你说的那样处理,但不知道具体该怎么做,也担心仍然可能造成读写冲突(一边把数据读入缓冲,一边用一个线程从缓冲中取出数据来分包处理,难道这样没有可能造成读写冲突吗),请给一个类似处理的例子,万分感谢!
 
已经发送,自己看吧.
 
firstrose朋友:
我已经收到,非常感谢!可惜我现在没钱没学业没事业没身体没老婆,真是一直穷到一无所有,连分也仅剩这么可怜的10分了,全给你了,不要嫌少哟,呵呵,再一次感谢!!!
 
免了,不过我关心的是问题解决没有?
 
后退
顶部