logo资料库

Delphi 中TcpServer和TcpClient用法.doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
IdTcpServer/IdTcpClient
IdTcpServeruses IdContext //需要引用属性,方法:IdTCPServ
在DelPhi2007 中 使用Indy 的TCP连接教程(一)
在Delphi 2007中使用Indy10的TCP连接的教程(系列二)
在Delphi 2007中使用Indy10的TCP连接教程(系列三)
做 服务端如何针对一个客户进行主动发送信息!     首先 服务端 要针对某一个用户进行发送信息
procedure TForm6.ConetClick(Sender: TObject);var
IdTcpServer/IdTcpClient IdTcpServer uses IdContext //需要引用 属性,方法: IdTCPServer.Active :=True; //开启服务器 IdTCPServer1.Bindings.Add.IP := '127.0.0.1';//绑定 IP IdTCPServer1.Bindings.Add.Port := 7956;//绑定端口 事件: OnConnect : 客户端连接成功触发 OnDisConnect : 客户端断开触发 OnExeCute : 收到客户端数据触发 例子 //像所有客户断发送数据 var I: Integer; Context: TIdContext; begin with IdTCPServer1.Contexts.LockList do try for I := 0 to Count - 1 do begin Context := TIdContext(Items[I]); Context.Connection.IOHandler.Write('Hello,everybod y!'); end; finally IdTCPServer1.Contexts.UnlockList; end; end; //向某个客户发送数据 var I: Integer; Context: TIdContext; begin with IdTCPServer1.Contexts.LockList do try for I := 0 to Count - 1 do begin Context := TIdContext(Items[I]); if Context.Binding.PeerIP <> '192.168.10.90' then continue;
Context.Connection.IOHandler.Write('Hello!'); end; finally IdTCPServer1.Contexts.UnlockList; end; end; IdTcpClient 属性,方法: ConnectTimeOut:连接超时 Host:主机 IP 或域名 IPVersion:Ip 版本 ipv4 or ipv6 Name:控件名 Port:主机端口 ReadTimeOut:读取超时 IdTCPClient1.Connect; //连接服务端 IdTCPClient1.Disconnect;//端开连接 IdTCPClient1.Connected;//是否连接成功 返回 true 连接成功 IdTCPClient1.IOHandler.WriteLn('aa');// 向服务端发送数据 OnWork 事件 AWorkMode=wmRead 表示有收到数据
在 DelPhi2007 中 使用 Indy 的 TCP 连接教程 (一) 首先 先说明下 为什么要用 INDY10 最新的 indy10 可以基于 win32 上的程(Fiber) API. 什么叫 Fiber API 呢,这里是解释: 纤程(Fiber) — 可以从 32 位版本的 Windows? 中使用的轻量级线程 处理对象 — 在很多方案中都很有用。由于线程是宝贵资源,因此您有时不希望 将整个 OS 线程专门用于执行简单的任务。通过纤程,可以比线程更严密地控制 任务的调度,因为是您而不是 OS 负责管理它们。由于它们具有较少的开销,因 此当您切换上下文时,它们还更加快速。此外,因为是由您控制纤程,所以对于 它们而言,通常可以更容易地跟踪同步问题。 不过这个特性,现在只有针 对 delphi7 有用。 端口重叠可以让你的服务器承担更多的用户。indy10 值得一用。 indy10 支持完成端口和纤程,性能有了巨大提升! ===================================================================== =========== 我们先打开 DelPhi2007 工具吧! 首先 我们 做好一个简单的客户端 先新建一个窗口程序 拖入一个 TCP 客户端控件 还有 3 个按钮 一个文本框 是 连接 断开 和 发生 设置一下 IdTCPClient 控件的属性 Host :127.0.0.1 Post:3000 下面 我们来对连接按钮做事件 procedure TForm6.ConetClick(Sender: TObject); begin try if not (IdTCPClient1.Connected) then IdTCPClient1.Connect; ShowMessage('连接成功'); except
ShowMessage('连接失败'); end; end; 接着 我们来做一下服务端的程序 先新建一个窗口程序 拖入一个 TCP 服务端控件 两个按钮 以及一个 TMemo 用来 显示信息 Bindings 0.0.0.0:3000 DefaultPort 3000 我们在“启动服务” 按钮上 的事件 procedure TForm6.Button1Click(Sender: TObject); begin IdTCPServer1.Active:= true; end; 启动时 只要将其 Active 设置为 true 既启动了服务 而关闭则同样设置为 False 接下来 我们要对 IdTCPServer1 的 OnExecute 事件做处理! 选择控件 EVENTS 栏双击 OnExecute 在这里 代码我们暂时这样写 procedure TForm6.IdTCPServer1Execute(AContext: TIdContext); begin exit; end; TIdContext 需要 uses IdContext 好 到这里 运行下服务器 和 客户端 然后 启动服务器 和 连接服务器 好 已经可以连接得上了吧! 但是 因为 我们在服务器监听的部分退出了 所以 并没有保持着连接 现在 我们 修改一下 代码吧 我们把 OnExecute 代码修改如下 procedure TForm6.IdTCPServer1Execute(AContext: TIdContext); var Swp:String; begin try AContext.Connection.IOHandler.CheckForDisconnect(True, True); Swp:=AContext.Connection.IOHandler.ReadLn(); Memo1.Lines.Add(Swp) ; finally
end; end; 我们对客户端也修改一下 procedure TForm6.ConetClick(Sender: TObject); begin try if not (IdTCPClient1.Connected) then begin IdTCPClient1.Connect; IdTCPClient1.IOHandler.writeln('lianjie'); ShowMessage('连接成功'); end; except ShowMessage('连接失败'); end; end; 在运行测试一下 当按下连接按钮后 服务器上的文本框里 加入了一行 'lianjie' 字符串而其再 次点击连接已经无效 而刚刚每次点击一次 都会提示一次连接成功 仔细看代码 就发现 在连接的时候判断了是否已经连接了如果已经保持连接了哪么就不会在 做下面的代码!从而可知现在的连接已经是保持着的了! 那好我们来发个信息 看下是否真的可以连接了 在发送按钮上的事件 procedure TForm6.SendClick(Sender: TObject); var Str:String; begin Str:=Edit1.Text; if(IdTCPClient1.Connected) then IdTCPClient1.IOHandler.writeln(Str); end; 好 我们来测试一下 是不是连接以后真的可以向服务器发送数据了呢? 看到了吧! 是不是可以发送数据了!
在 Delphi 2007 中使用 Indy10 的 TCP 连接的教程(系 列二) 服务器怎么样区别数据到底是哪一个发送过来的呢,或者服务器如何对其回复数 据呢!~ 先针对回复对应的客户端发送过来的数据!已经客户端接受并显示服务器反馈回 来的数据! 我们修改服务器上的 OnExecute 代码如下! procedure TForm6.IdTCPServer1Execute(AContext: TIdContext); var Swp:String; begin try AContext.Connection.IOHandler.CheckForDisconnect(True, True); Swp:=AContext.Connection.IOHandler.ReadLn(); if(Swp<>'')then AContext.Connection.IOHandler.WriteLn('服务器已经收到您发来的信息: '+Swp); Memo1.Lines.Add(Swp) ; finally end; end; 在客户端里我们加入一个 TMemo 用来接受服务器发来的数据信息! 然后我们在来看客户端的代码! 在连接和发送按钮上的事件修改为 procedure TForm6.ConetClick(Sender: TObject); begin try if not (IdTCPClient1.Connected) then begin IdTCPClient1.Connect; IdTCPClient1.IOHandler.writeln('lianjie'); Str:=IdTCPClient1.IOHandler.ReadLn(); Memo1.Lines.Add(Str);
ShowMessage('连接成功'); end; except ShowMessage('连接失败'); end; end; procedure TForm6.SendClick(Sender: TObject); var Str:String; begin Str:=Edit1.Text; if(IdTCPClient1.Connected) then IdTCPClient1.IOHandler.writeln(Str); try Str:=IdTCPClient1.IOHandler.ReadLn(); Memo1.Lines.Add(Str); finally end; end; 我们编译后 打开多个客户端进行测试 就会发现 对不同客户端服务器会分别的 响应并对其回复内容 互不干扰! 做到这里 大家也知道客户端如果要发送一条数据才能相应的去读取一条数据! 可能有些人会想到利用定时器对数据进行定时读取!~ 这样也是一个办法!但是 在程序操作中 由于数据太快而没有及时读取就会出现数据丢失掉了!那我们要 用什么方法才能很好的对数据进行准确读取呢!在这里我使用了线程!启用一个 线程利用一个死循环对数据进行读取!一旦有数据就读取出来并放在一个 StringList 里 供我们使用! 好我们一步步的来实现! 我们先来做一全局变量的定义 新建一全局变量页面 MainUnit.pas 我们先声明两个全局变量 代码如下 unit MainUnit; interface uses Classes,SyncObjs; var M_Lock : TCriticalSection;//临界区,多线程同步问题。TCriticalSection M_MsgList:TStringList; implementation
end. 然后我们在主程序的窗口创建事件里创建这两个对象 procedure TForm6.FormCreate(Sender: TObject); begin M_MsgList:=TStringList.Create; M_Lock end; :=TCriticalSection.Create; 接下来我们把这个页面引用到程序中 以及线程代码中 线程页面 MyThread.pas 代码如下 unit MyThread; interface uses Classes,SysUtils,Forms,Windows,Variants,idIOHandler,MainUnit; type TMainThread = class(TThread) private protected procedure Foo; procedure Execute;Override; public Constructor Create(Suspended:Boolean); end; implementation uses Client; Constructor TMainThread.Create(Suspended:Boolean);//创建线程 Begin inherited Create(Suspended); FreeOnTerminate:=True; End; procedure TMainThread.Foo; var Msg:string; bool: boolean; begin bool:=true; while bool do begin try Msg:= Form6.IdTCPClient1.IOHandler.ReadLn; if(Msg='') then
分享到:
收藏