Socket的问题,高手速速入内!(200分)

  • 主题发起人 主题发起人 pingpingniu
  • 开始时间 开始时间
P

pingpingniu

Unregistered / Unconfirmed
GUEST, unregistred user!
我用Delphi的ClientSocket作了一个客户端的程序,我想进行多次发送和接收,我是这样做的:
在连接事件中发送数据,在OnRead事件中让Socket关闭,做一个计数器控制发送个数,然后再打开
Socket。
但是一个奇怪的现象出现了,当程序在运行时,我点击别的界面,此程序就停止发送。就算我
不点击别的界面,程序也经常停止发送,而且停止的地方也不一样,有时候发送几千个才停,有时
候几十个就停了,有哪位高手能告诉我为什么吗?是这个控件有Bug还是我程序本身有问题?
 
为什么要让Socket关闭?
如果要计数,可以在onsend中做。
把代码贴上来,看看才能知道。
 
to woodstock
如何控制连续发送的次数,能说详细点吗?
在onsend怎么做?
 
还有,ClientSocket控件没有OnSend事件!
 
在连接事件中发送数据就不行吗?
 
我试了试,在onwrite中更不行,只能发送一条。
我用自己原来的方法,只要不点击别的东西还可以发很多条,
但是只要点击了别的东东,不是停止发送就是报错!
大家帮帮忙吧!

 
我把源码贴上,请大家帮忙看看!(Socket为异步方式)
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
if ClientSocket1.Active then ClientSocket1.Close;
ClientSocket1.Open;
count := 0;
end;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ClientSocket1.Socket.SendText('aaa');
end;

Procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
showmessage('error');
end;


//每收到一条回音再关闭和打开一次Socket(必须收到再发送)
//但我不想用同步方式作,可以吗?
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
strReturn: string;
i: integer;
begin
strReturn := ClientSocket1.Socket.ReceiveText;
if ClientSocket1.Active then
ClientSocket1.close;
count := count + 1;
edit.Text := inttostr(count); //用于判断在发送了多少次后停止发送
if count < 5000 then //发5000次
begin
if ClientSocket1.Active then
begin
sleep(1000); //由于莫名停止,以为是发送太快,故而给一延时
ClientSocket1.close;
showmessage('没有断开连接!');
end;

ClientSocket1.Open;

end;
 
没有必要不停打开/关闭!!!!!!!!!!!
你的用法似乎不对,假设服务器接受到你的'aaa'请求之后有6000字节要回复,一般要分3个包完成
也就是要触发3次ClientSocket1Read (2048,2048,1904) 但是你在接受第一个2048之后就把连接关闭了!!!
---你破坏了正常的会话过程!!!!!重写吧.

 
to tianhf:
我是不想不停的开关,可是我试过了很多种办法,包括
在OnWrite事件里写,用计数器,用定时器,都不灵!
我初学,还望指点深一点!最好有源码!
谢谢!
 
不知你要干什么,使用什么协议,一般要先知道包的大小.
OnWrite的确在一个Connect只执行一次.
我理解你是否发出 aaa1 要求对方返回信息,发 aaa2 对方再返回信息,aaa3 ......
 
不是,是发同样的消息,得到同样的回复。
主要是用于测试!
 
回复包多大?
 
是一个结构,很小,不用拆分的。
 
我想你应当在窗体中引入控件TApplicationEvents,其中有一个事件onidle可以让你操作
你想操作的事件,只要你的系统有空闲,即使失去焦点也没关系!
procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
var Done: Boolean);
begin

//do your active

end;
 
加一个时钟控件 timer1 100ms触发
加一个全局变量 haveRecv

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
count := count + 1;
edit.Text := inttostr(count); Application.ProcessMessages;
haveRecv:=true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if not haveRecv then exit;//没有接收到数据,等待下一个时钟周期
haveRecv:=false;
ClientSocket1.Socket.SendText('aaa');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
haveRecv:=false;
end;

//当按某个按钮时 ClientSocket1.Active :=false; 使其停止!!!
 
我要先发,然后才能收到!所以我在第一次连接时必须要发送!
这样的话,在哪触发定时器?
 
to tianhf:
我试了你的方法,还是不行!
只发一次,就不再发了!
原程序如下:

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
count := count + 1;
edit1.Text := inttostr(count);
haveRecv:=true;
Application.ProcessMessages;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
haveRecv:= false;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if not haveRecv then exit;//没有接收到数据,等待下一个时钟周期

haveRecv:=false;
ClientSocket1.Socket.SendBuf(arrayRecord,sizeof(arrayRecord));

end;

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
ClientSocket1.open;
count := 0;
end;

end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ClientSocket1.Socket.SendText('aaa');
timer1.Enabled := true;
end;

最后,它就一直停在OnTimer事件。
 
服务器端程序是你编的吗?是否一个会话之后它中断了连接????
procedure TForm1.ClientSocket1Disconnect(Sender: TObject;Socket: TCustomWinSocket);
begin
edit1.text:='服务器中断了会话';
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
edit1.text:='Socket 错误';
end;


 
我是路过的,呵呵,

procedure TForm1.Timer1Timer(Sender: TObject);
begin

timer1.enabled:=false; //------------

if not haveRecv then exit;//没有接收到数据,等待下一个时钟周期
haveRecv:=false;
ClientSocket1.Socket.SendText('aaa');

timer1.enabled:=true; //------------

end;
 
后退
顶部