关于Delphi Indy 控件里IdTcpClient 的 疑问
TClientHandleThread=class(TThread)privateCB:TCommBlock;procedureHandleInput;protected...
TClientHandleThread = class(TThread)
private
CB: TCommBlock;
procedure HandleInput;
protected
procedure Execute; override;
end;
var
ClientFrmMain: TClientFrmMain;
ClientHandleThread: TClientHandleThread; // variable (type see above)
implementation
{$R *.DFM}
procedure TClientHandleThread.HandleInput;
begin
if CB.Command = 'MESSAGE' then
ClientFrmMain.IncomingMessages.Lines.Add (CB.MyUserName + ': ' + CB.Msg)
else
if CB.Command = 'DIALOG' then
MessageDlg ('"'+CB.MyUserName+'" sends you this message:'+#13+CB.Msg, mtInformation, [mbOk], 0)
else // unknown command
MessageDlg('Unknown command "'+CB.Command+'" containing this message:'+#13+CB.Msg, mtError, [mbOk], 0);
end;
procedure TClientHandleThread.Execute;
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;
procedure TClientFrmMain.CBClientActiveClick(Sender: TObject);
begin
if CBClientActive.Checked then
begin
try
Client.Connect(10000); // in Indy < 8.1 leave the parameter away
ClientHandleThread := TClientHandleThread.Create(True);
ClientHandleThread.FreeOnTerminate:=True;
ClientHandleThread.Resume;
except
on E: Exception do MessageDlg ('Error while connecting:'+#13+E.Message, mtError, [mbOk], 0);
end;
end
else
begin
ClientHandleThread.Terminate;
Client.Disconnect;
end;
ButtonSend.Enabled := Client.Connected;
CBClientActive.Checked := Client.Connected;
end;
procedure TClientFrmMain.ButtonSendClick(Sender: TObject);
var
CommBlock : TCommBlock;
begin
CommBlock.Command := EditCommand.Text; // assign the data
CommBlock.MyUserName := Client.LocalName;
CommBlock.Msg := EditMessage.Text;
CommBlock.ReceiverName := EditRecipient.Text;
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
end;
我的问题是它创建的这个监听线程,是怎么做到的有信息来时才进去显示操作(Synchronize(HandleInput);
)的,我想的是它既然是个线程,只要Terminated为真,它就会一直的读呀,而会把空消息也读进来的。我在线程里下过断点,实际情况是只有有消息进来时才进行显示操作,没消息时进不来。。这是为什么,请大家知道的解解惑。 展开
private
CB: TCommBlock;
procedure HandleInput;
protected
procedure Execute; override;
end;
var
ClientFrmMain: TClientFrmMain;
ClientHandleThread: TClientHandleThread; // variable (type see above)
implementation
{$R *.DFM}
procedure TClientHandleThread.HandleInput;
begin
if CB.Command = 'MESSAGE' then
ClientFrmMain.IncomingMessages.Lines.Add (CB.MyUserName + ': ' + CB.Msg)
else
if CB.Command = 'DIALOG' then
MessageDlg ('"'+CB.MyUserName+'" sends you this message:'+#13+CB.Msg, mtInformation, [mbOk], 0)
else // unknown command
MessageDlg('Unknown command "'+CB.Command+'" containing this message:'+#13+CB.Msg, mtError, [mbOk], 0);
end;
procedure TClientHandleThread.Execute;
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;
procedure TClientFrmMain.CBClientActiveClick(Sender: TObject);
begin
if CBClientActive.Checked then
begin
try
Client.Connect(10000); // in Indy < 8.1 leave the parameter away
ClientHandleThread := TClientHandleThread.Create(True);
ClientHandleThread.FreeOnTerminate:=True;
ClientHandleThread.Resume;
except
on E: Exception do MessageDlg ('Error while connecting:'+#13+E.Message, mtError, [mbOk], 0);
end;
end
else
begin
ClientHandleThread.Terminate;
Client.Disconnect;
end;
ButtonSend.Enabled := Client.Connected;
CBClientActive.Checked := Client.Connected;
end;
procedure TClientFrmMain.ButtonSendClick(Sender: TObject);
var
CommBlock : TCommBlock;
begin
CommBlock.Command := EditCommand.Text; // assign the data
CommBlock.MyUserName := Client.LocalName;
CommBlock.Msg := EditMessage.Text;
CommBlock.ReceiverName := EditRecipient.Text;
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
end;
我的问题是它创建的这个监听线程,是怎么做到的有信息来时才进去显示操作(Synchronize(HandleInput);
)的,我想的是它既然是个线程,只要Terminated为真,它就会一直的读呀,而会把空消息也读进来的。我在线程里下过断点,实际情况是只有有消息进来时才进行显示操作,没消息时进不来。。这是为什么,请大家知道的解解惑。 展开
展开全部
procedure TClientHandleThread.Execute;
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;
请楼主自己看看这个程序
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
这段如果没有数据包的话会抛出异常。所以就不会执行Synchronize(HandleInput);
也就不会处理消息了。直接跳到EXCEPT里面去了。程序循环执行。不影响正常运行。
一般来说INDY的TCPCLIENT里面没有ONREAD事件。没办法接受消息。所以必须开一个监听线程来接收服务器发来的信息。灰鸽子的工作原理就是这样的。
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;
请楼主自己看看这个程序
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
这段如果没有数据包的话会抛出异常。所以就不会执行Synchronize(HandleInput);
也就不会处理消息了。直接跳到EXCEPT里面去了。程序循环执行。不影响正常运行。
一般来说INDY的TCPCLIENT里面没有ONREAD事件。没办法接受消息。所以必须开一个监听线程来接收服务器发来的信息。灰鸽子的工作原理就是这样的。
追问
先谢谢你的回答,我断点是下在TClientHandleThread.Execute里面的if not ClientFrmMain.Client.Connected then这一行上,还没到try那里呢,没消息进来的话就到不了断点,着实困惑
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
应该是停在 ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB)); 这里了。
Indy 用的是阻塞式。所以会等待。
Indy 用的是阻塞式。所以会等待。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
mark 一下. 坐等高手来解
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询