真的是高手吐血神秘问题,大家帮一把吧(200分)

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

archy

Unregistered / Unconfirmed
GUEST, unregistred user!
一个server/client通讯程序,client中单击btn1激发
var str1,str2:string;
str1=:'abcdefg'; str2:='2';
clientsocket1.Socket.SendText(str1);
clientsocket1.socket.SendText(str2);

server中用两个Socket.ReceiveText如此接受
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var str1,str2:string;
if receivecount<1 then // str1,str2初值为空'',receivecount=0;
begin
str1:=Socket.ReceiveText;
inc(receivecount);
end
else
begin
str2:=Socket.ReceiveText;
memo2.Clear;
memo2.Lines.Append(str1);
memo2.Lines.Append(str2);
receivecount:=0;
str1:=''; str2:='';
end;

我发现一个十分奇怪的问题,若我click btn1很快2下(相当于双击),则server的memo2中会显示
abcdefg2
abcdefg
很明显client的第一次的clientsocket1.Socket.SendText(str1);
clientsocket1.socket.SendText(str2);
因传送太快被server的第一个一个str1:=Socket.ReceiveText;统统吃掉了,
第二次的clientsocket1.Socket.SendText(str1);则被server中的str2:=Socket.ReceiveText;接收,
而第二次的clientsocket1.socket.SendText(str2);则丢失了

若我click btn1较慢两下或一下,则server的memo2中会正确的显示
abcdefg
2
我要的结果
百思不得其解,调试也看不出端倪,恳请高手指教望,怎样避免此种情况呢?
 
一个绕过去的法子:
加一个Timer1,设其初始Enaled为False,在btn1Click中加入
btn1.Enabled := False;
Timer1.Enabled := True;
在Timer1的OnTimer中加入
btn1.Enabled := True;
Timer1.Enabled := False;
只要设置Timer1的Interval在50--100之间即可避免双击
 
Delphi Help:
TCustomWinSocket.SendText
SendText returns 0 if the string was successfully written. It returns a nonzero value
if the writing must be postponed. When SendText returns a nonzero value, it must be
called again later to write the value over the connection.

因此,可以通过在程序中判断SendText的返回值来确定是否要进行等待。
具体过程大致如下:
while clientsocket1.Socket.SendText(str1)<>0 do ; //无限循环,直到完全发出

另外,为了安全起见,建议在Btn1Click过程中的开头和结尾分别加上:
Btn1.Enabled:=false;
Btn1.Enabled:=true;
 
i add a sleep(700) to run normally
 
接受答案了.
 
后退
顶部