我想做一个聊天室,经过考虑决定用TIdTCPClient和TIdTCPServer两个控件,服务器端使用起来还可以,可以客户端接收数据就成了问题,看了好多这方面的例子,基本上都是通过TTimes控件的OnTimer事件里写程序来读取接收到的数据的,我试着这样处理,可是客户端程序一运行就死在那里不动,不知是何原因?请教:1、如何正确使用TIdTCPClient控件读取接收到的数据?2、如果一定要用TTimes控件,请问有什么地方要注意的?怎样才能让客户端程序不死?3、希望能发一个好的例子给我([email protected])!多谢!!!!
解决方案 »
- quickreport 如何对QRDBText绑定列下面出个合计啊?
- 如何获取combobox显示的值
- DBGrid显示Excel数据的问题
- 远程数据库中Image类型字段的导入问题
- 强烈建议建立语音论坛室,大家认为如何?
- 用Delphi如何定义excel中的工作簿为文本格式,百分比格式,水平居中,垂直居中。
- 哪里有QuickReport的详细资料?
- TMediaplayer能播mp3吗???,在winxp下好使,但在win2000为什么说设备类型未找到????
- 用Sqlserver库错误提示为“将截断字符串或二进制数据”
- 请问那儿有delphi ado方面的书down
- ★★★求助★★★
- 如何对视频进行广播???全部家产!!!
procedure TFormMain.BtnSendClick(Sender: TObject);beginLbLog.Items.Add('DATA ' + EdtData.Text);with IdTCPClient dobegintryWriteLn('DATA ' + EdtData.Text);LbLog.Items.Add(ReadLn())exceptLbLog.Items.Add('发送数据失败!');IdTCPClient.Disconnect();LbLog.Items.Add('同主机 ' + EdtHost.Text + ' 的连接已断开!');BtnConnect.Enabled := True;BtnSend.Enabled := False;BtnDisconnect.Enabled := False;end;//end tryend;//end withend;
procedure TFormMain.BtnDisconnectClick(Sender: TObject);varReceived: string;beginLbLog.Items.Add('QUIT');tryIdTCPClient.WriteLn('QUIT');finallyIdTCPClient.Disconnect();LbLog.Items.Add('同主机 ' + EdtHost.Text + ' 的连接已断开!');BtnConnect.Enabled := True;BtnSend.Enabled := False;BtnDisconnect.Enabled := False;end;//end tryend;
在“连接”按钮事件响应过程中,首先根据用户输入设置IdTCPClient的主机和端口,并调用IdTCPClient的Connect方法向服务器发出连接请求。然后调用ReadLn方法读取服务器应答数据。在“发送”按钮事件响应过程中,调用WriteLn方法写DATA命令,向服务器发送数据。在“断开”按钮事件响应过程中,向服务器发送QUIT命令,并调用Disconnect方法断开连接。程序中还包含有通信信息记录和异常处理的代码。服务器程序代码服务器程序片断如代码列表2所示。代码列表2procedure TFormMain.BtnStartClick(Sender: TObject);beginIdTCPServer.DefaultPort := StrToInt(EdtPort.Text);IdTCPServer.Active := True;BtnStart.Enabled := False;BtnStop.Enabled := True;LbLog.Items.Add('服务器已成功启动!');end;
procedure TFormMain.BtnStopClick(Sender: TObject);beginIdTCPServer.Active := False;BtnStart.Enabled := True;BtnStop.Enabled := False;LbLog.Items.Add('服务器已成功停止!');end;
procedure TFormMain.IdTCPServerConnect(AThread: TIdPeerThread);beginLbLog.Items.Add('来自主机 '+ AThread.Connection.Socket.Binding.PeerIP+ ' 的连接请求已被接纳!');AThread.Connection.WriteLn('100: 欢迎连接到简单TCP服务器!');end;
procedure TFormMain.IdTCPServerExecute(AThread: TIdPeerThread);varsCommand: string;beginwith AThread.Connection dobeginsCommand := ReadLn();FLogEntry := sCommand + ' 来自于主机 '+ AThread.Connection.Socket.Binding.PeerIP;AThread.Synchronize(AddLogEntry);if AnsiStartsText('DATA ', sCommand) thenbeginFReceived := RightStr(sCommand, Length(sCommand)-5);WriteLn('200: 数据接收成功!');AThread.Synchronize(DisplayData);endelse if SameText(sCommand, 'QUIT') then beginFLogEntry := '断开同主机 '+ AThread.Connection.Socket.Binding.PeerIP+ ' 的连接!';AThread.Synchronize(AddLogEntry);Disconnect;endelse beginWriteLn('500: 无法识别的命令!');FLogEntry := '无法识别命令:' + sCommand;AThread.Synchronize(AddLogEntry);end;//endifend;end;
procedure TFormMain.DisplayData();beginEdtData.Text := FReceived;end;
procedure TFormMain.AddLogEntry();beginLbLog.Items.Add(FLogEntry);end;
“启动”按钮设置IdTCPServer 的Active属性为True来启动服务器,“停止”按钮设置Active属性为False来关闭服务器。IdTCPServerConnect方法作为IdTCPServer 的OnCorrect事件响应过程,向客户端发送欢迎信息。OnCorrect事件在一个客户连接请求被接受时发生,为该连接创建的线程AThread被作为参数传递给IdTCPServerConnect方法。IdTCPServerExecute方法是IdTCPServer 的OnExecute事件响应过程。OnExecute事件在TIdPeerThread对象试图执行其Run方法时发生。OnExecute事件与通常的事件有所不同,其响应过程是在某个线程上下文中执行的,参数AThread就是调用它的线程。这一点很重要,它意味着可能有多个OnExecute事件响应过程被同时执行。在连接被断开或中断前,OnExecute事件响应过程会被反复执行。在IdTCPServerExecute方法中,首先读入一条指令,然后对指令进行判别。如果是DATA指令,就解出数据并显示它。如果收到的是QUIT指令,则断开连接。需要特别指出的是,由于IdTCPServerExecute方法在某一线程上下文中执行,因此显示数据和添加事件记录都是将相应的方法传递给Synchronize调用来完成的。运行程序运行客户端和服务器程序,按如下流程进行操作:1.按服务器程序的“启动”按钮启动服务器;2.按客户程序的“连接”按钮,建立同服务器的连接;3.在客户程序的待发送数据编辑框中输入“Hello, Indy!”,并按“发送”按钮发送数据;4.按客户程序的“断开”按钮,断开同服务器的连接;5.按服务器程序的“停止”按钮停止服务器。