如何使用TTcpServer控件

(摘自)http://hi.baidu.com/kvkens/blog/item/a7b6ca176b79c80cc93d6d18.html

一直想学习一下网络编程,苦于无法找到相关的资料,以前也写过一些网络程序,但那些都是用Indy的控件,使用起来相对较为简单,无法接触到底层的东西。最近安装了VISTA操作系统后,发现该系统彻底的不支持Delphi 7了。在网上下载了Delphi 2006 Lite版,少了很多控件,其中就包括了以前用的Indy控件,但幸运的是可以使用TTcpServerTTcpClient控件。但这个控件基本上不会使用,在网上查找相关的资料也相当的困难,论坛中基本上是问这个控件怎么使用的,回答的也多是一些错的。另外该死的VISTA系统也不支以前的老的帮助,幸运的是该控件带有源代码,经过几天的研究。终于了解了该控件的使用方法。下面介绍一下该控件的使用方法以及相关的注意事项。

这个控件的属性不多,其他的属性没什么好介绍的,都可以顾名思义的设就形了,需要一提的是BlockMode,本文着重介绍当BlockModebmBlocking的使用方法。这种阻塞模式为线程阻塞,其实也就是阻塞模式,当调用Open的方法后,系统自动会开启一个线程来监控是否有客户端连接。如果有客户端的连接过来后,系统会自动为每个客户端提供一个线程。这个线程会有一个默认线程类来实现的,但该类基本上没有什么功能,如果想使用TTcpServer这个类的话,那么这个类的代码是必须要重写的。

客户端线程类的写法:

   TServerThread=class(TClientSocketThread)
  private
     s:string;
  protected
    procedure
SyncProc;override;
  end;

{ TServerThread }

procedure TServerThread.SyncProc;
begin
   form1.Memo1.Lines.Add(formatdatetime(
'mm-dd hh:mm:ss :',now)+s);
end;

该控件提供的事件也不是很多,需要注意使用的有两个,一个是OnGetThread,另外一个是OnAccept。只要在这两个里面进行编码就基本上就可以使用这个类了。OnGetThread里面需要写的代码是用自己的线程类来替换掉默认的主线程类。OnAccept里面需要写的代码是主线程类中需要处理的任务,如读取客户端的消息,向客户端回应等。需要注意的是OnAccept的代码是在线程中运行,需要写成死循环,除非到该客户端中止为止,并且还需要不停的去检查该线程是否中止。另外如果访问主线程中的资源,需要进行同步处理。以下是这个两个方法的代码示例:

1OnGetThread中取代线程的代码

procedure TForm1.TcpServer1GetThread(Sender: TObject;
  var ClientSocketThread: TClientSocketThread);
begin
   ClientSocketThread:=TServerThread.Create(tcpserver1.ServerSocketThread);
end;

2OnAccept中的代码

procedure TForm1.TcpServer1Accept(Sender: TObject;
   ClientSocket: TCustomIpClient);
var T:TServerThread;
begin
   T:=TServerThread(ClientSocket.GetThreadObject);
   T.s :=clientsocket.RemoteHost +
'已连接';
   t.SyncProc
  while not T.Terminated and clientsocket.Connected do
  begin
    if
ClientSocket.WaitForData(
0) then
    begin

       t.s:=ClientSocket.Receiveln();
       ClientSocket.Sendln(
'Re:'+t.s);
      if t.s=
'QUIT' then ClientSocket.Disconnect
      else T.SyncProc;
    end;
  end;
   t.s :=clientsocket.RemoteHost +
'已断开';

   t.SyncProc
end;

以上的代码写好后,该控件就可以正常工作了。这个程序的功能比较简单,客户发过来消息后,自动回应客户一条信息。如果收到客户退出的消息后,就会自动退出线程,并中止与客户端的连接。

总而言之,这个控件封装的还是不错的,只需要简单的和行代码就可以实现复杂的服务器程序。下面是这个程序完整的例子:

unit Unit1;
{
  
项目: TTcpServer 示例程序
  
作者: 黄涛
  
创建: 2008-4-25
}

interface

uses

   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, Sockets, StdCtrls;

type
   TForm1 = class(TForm)
     btStart: TButton;        
//开始终止按钮
     Server: TTcpServer;      
//服务器控件
     mmLog: TMemo;            
//日志控件
    procedure ServerGetThread(Sender: TObject;    
//获取线程的事件
      var ClientSocketThread: TClientSocketThread);
    
//客户端连接事件
    procedure ServerAccept(Sender: TObject; ClientSocket: TCustomIpClient);
    procedure btStartClick(Sender: TObject);
//点击启动中止事件
    procedure AddLog(msg:String);
//添加日志
  private
    
{ Private declarations }
  public
    
{ Public declarations }
  end;

   TServerThread=class(TClientSocketThread)   
//客户端线程
  private
     s:string;
  protected
    procedure
SyncProc;override;    
//同步的方法
  end;

var
   Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AddLog(msg: String);     
//添加日志
begin
   mmLog.Lines.Add(formatdatetime(
'mm-dd hh:mm:ss :',now)+msg);
end;

procedure TForm1.btStartClick(Sender: TObject);
begin
  if
server.Active then Server.close
  else Server.Open  
  if Server.Active then
  begin

     btStart.Caption :=
'停止'
     AddLog(
'服务器已启动')
  end
  else
  begin

     btStart.Caption :=
'启动';
     AddLog(
'服务器已停止');
  end;
end;

procedure TForm1.ServerAccept(Sender: TObject;
   ClientSocket: TCustomIpClient);
var T:TServerThread;
begin
   T:=TServerThread(ClientSocket.GetThreadObject);
//获取该线程的对象句柄
   T.s :=clientsocket.RemoteHost +
'已连接';
   T.ExecuteSyncProc;     
//添加已连接的日志
  while not T.Terminated and clientsocket.Connected do
  begin
   
//该线程未中止和客户端未中止连接时执行
    if ClientSocket.WaitForData(
0) then
    begin
  
//如果客户端发送数据
       t.s:=ClientSocket.Receiveln();   
//接收数据
       ClientSocket.Sendln(
'Re:'+t.s);  //回复客户端
      if t.s=
'QUIT' then ClientSocket.Disconnect //如果是退出指令,则断开连接
      else T.SyncProc;
//否则添加日志
    end;
  end;
   t.s :=clientsocket.RemoteHost +
'已断开';   //添加断开客户端的日志
   T.ExecuteSyncProc;
end;

procedure TForm1.ServerGetThread(Sender: TObject;
  var ClientSocketThread: TClientSocketThread);
begin     
//用自己的线程取代标准的端线程
   ClientSocketThread:=TServerThread.Create(Server.ServerSocketThread);
end;

{ TServerThread }

procedure TServerThread.SyncProc;
begin
   Form1.AddLog(s);   
//添加日志
end;

end.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值