套接字(Socket)编程的基本方法(供初学者参考)
在Delphi中,套接字(Socket)编程用到的基本类是TServerSocket与TClientSocket。这两个类全部位于ScktComp单元中。其类型定义如下:
type TServerSocket = class (ScktComp.TCustomServerSocket);
TClientSocket = class (ScktComp.TCustomSocket)。
在编写程序时,首先要对TServerSocket(在服务器端)与TClientSocket(在客户端)进行实例化。对于TServerSocket的对象,主要设置其服务类型(ServerType)与端口(Port)的属性,然后编写“OnClientRead”事件处理程序的代码,处理来自客户机的请求。如要启动服务器,设置TServerSocket对象的Active属性为真(即Active := True),如要停止服务器,则设置TServerSocket对象的Active属性为假(即Active := False)。
对于TClientSocket的对象,主要设置对方服务器的服务类型(ServerType)、端口(Port)以及IP地址(Address)的属性,之后编写“OnConnect与OnRead”事件处理程序的代码“OnConnect”事件处理程序用来检查与服务器连接成功与否(必须在这里进行检查才有效),“OnRead”事件处理程序用来读取服务器发来的信息。如要连接服务器,设置TClientSocket对象的Active属性为真(即Active := True;注意:检查连接是否成功,必须在“OnConnect”事件处理程序中进行),如要断开与服务器的连接,则设置TClientSocket对象的Active属性为假(即Active := False)。
编程中需掌握的细节,见单元源码。
附件:
1、单元源码
///////////////////////////////////////////////////////////////////////////////////////////////////////////
unit MainUnit;
interface
uses ScktComp,
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type
TSvrCltSocke = class(TForm) GroupBox1: TGroupBox; GroupBox2: TGroupBox; btnSvrStart: TButton; btnSvrStop: TButton; btnExit: TButton; Label11: TLabel; editSvrMsg: TEdit; Label12: TLabel; lbSvrLog: TListBox; Label21: TLabel; editCltMsg: TEdit; btnConnect: TButton; btnSend: TButton; btnDisconnect: TButton; Label22: TLabel; lbCltLog: TListBox; procedure FormCreate(Sender: TObject); //-------------------------------------------------------------------------- procedure btnSvrStartClick(Sender: TObject); procedure btnSvrStopClick(Sender: TObject); //-------------------------------------------------------------------------- procedure btnConnectClick(Sender: TObject); procedure btnSendClick(Sender: TObject); procedure btnDisconnectClick(Sender: TObject); //-------------------------------------------------------------------------- procedure btnExitClick(Sender: TObject); private (* TServerSocket: Unit ScktComp Syntax type TServerSocket = class (ScktComp.TCustomServerSocket); //------------------------------------------------------------------------ TClientSocket: Unit ScktComp Syntax type TClientSocket = class (ScktComp.TCustomSocket); *) FServerSocket: TServerSocket; FClientSocket: TClientSocket; //-------------------------------------------------------------------------- procedure ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); //-------------------------------------------------------------------------- procedure ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); public property ServerSocket: TServerSocket read FServerSocket write FServerSocket; property ClientSocket: TClientSocket read FClientSocket write FClientSocket; end; var
SvrCltSocke: TSvrCltSocke; implementation
{$R *.dfm}
//建立并初始化服务器与客户机套接字(Socket)对象
//============================================================================== procedure TSvrCltSocke.FormCreate(Sender: TObject); begin ServerSocket := TServerSocket.Create(Application); ServerSocket.ServerType := stNonBlocking; ServerSocket.Port := 8888; ServerSocket.OnClientConnect := ServerSocketClientConnect; ServerSocket.OnClientDisconnect := ServerSocketClientDisconnect; ServerSocket.OnClientRead := ServerSocketClientRead; //---------------------------------------------------------------------------- ClientSocket := TClientSocket.Create(Application); ClientSocket.ClientType := ctNonBlocking; ClientSocket.Address := '127.0.0.1'; ClientSocket.Port := 8888; ClientSocket.OnConnect := ClientSocketConnect; end; //服务器编码
//============================================================================== //启动服务器 //------------------------------------------------------------------------------ procedure TSvrCltSocke.btnSvrStartClick(Sender: TObject); begin try ServerSocket.Active := True; if ServerSocket.Active then begin btnSvrStart.Enabled := False; btnSvrStop.Enabled := True; lbSvrLog.Items.Add('服务器已启动!'); end; except on E: Exception do lbSvrLog.Items.Add('服务器启动失败!(' + E.Message + ')'); end; end; //停止服务器
//------------------------------------------------------------------------------ procedure TSvrCltSocke.btnSvrStopClick(Sender: TObject); begin try ServerSocket.Active := False; if not ServerSocket.Active then begin btnSvrStart.Enabled := True; btnSvrStop.Enabled := False; lbSvrLog.Items.Add('服务器已停止!'); end; except on E: Exception do lbSvrLog.Items.Add('服务器停止失败!(' + E.Message + ')'); end; end; //客户机连接时服务器事件
//------------------------------------------------------------------------------ procedure TSvrCltSocke.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin lbSvrLog.Items.Add('已连接: ' + Socket.RemoteHost + '('+Socket.RemoteAddress + ')'); end; //客户机断开时服务器事件
//------------------------------------------------------------------------------ procedure TSvrCltSocke.ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin lbSvrLog.Items.Add('已断开连接: ' + Socket.RemoteHost + '('+Socket.RemoteAddress + ')'); end; //客户机发送数据时服务器事件
//------------------------------------------------------------------------------ procedure TSvrCltSocke.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); begin editSvrMsg.Text := Socket.RemoteHost + ': ' + Socket.ReceiveText; end; //客户机编码
//============================================================================== //连接服务器 //------------------------------------------------------------------------------ procedure TSvrCltSocke.btnConnectClick(Sender: TObject); begin try LbCltLog.Items.Add('正在连接...'); ClientSocket.Active := True; except on E: Exception do LbCltLog.Items.Add('连接失败!(' + E.Message + ')'); end; end; //连接后的事件
//------------------------------------------------------------------------------ procedure TSvrCltSocke.ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); begin if Socket.Connected then begin LbCltLog.Items.Add('连接成功!'); btnConnect.Enabled := False; btnSend.Enabled := True; btnDisconnect.Enabled := True; end; end; //发送数据
//------------------------------------------------------------------------------ procedure TSvrCltSocke.btnSendClick(Sender: TObject); begin try ClientSocket.Socket.SendText(editCltMsg.Text); except on E: Exception do MessageDlg(E.Message, mtError, [mbOK], 0); end; end; //断开连接
//------------------------------------------------------------------------------ procedure TSvrCltSocke.btnDisconnectClick(Sender: TObject); begin try LbCltLog.Items.Add('正在断开连接...'); ClientSocket.Active := False; if not ClientSocket.Active then begin LbCltLog.Items.Add('断开成功!'); btnConnect.Enabled := True; btnSend.Enabled := False; btnDisconnect.Enabled := False; end; except on E: Exception do LbCltLog.Items.Add('断开失败!(' + E.Message + ')'); end; end; //退出系统
//============================================================================== procedure TSvrCltSocke.btnExitClick(Sender: TObject); begin Application.Terminate; end; end.
2、与单元配套的.dfm文件
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
object SvrCltSocke: TSvrCltSocke
Left = 0 Top = 0 Caption = 'TServerSocket and TClientSocke' ClientHeight = 312 ClientWidth = 443 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object GroupBox1: TGroupBox Left = 0 Top = 0 Width = 443 Height = 129 Align = alTop Caption = #26381#21153#22120'(Server)[IP:127.0.0.1;Port:8888]' TabOrder = 0 ExplicitWidth = 494 object Label11: TLabel Left = 8 Top = 28 Width = 60 Height = 13 Caption = #25509#25910#30340#25968#25454 end object Label12: TLabel Left = 44 Top = 47 Width = 24 Height = 13 Caption = #26085#24535 end object btnSvrStart: TButton Left = 360 Top = 25 Width = 75 Height = 21 Caption = #21551#21160 TabOrder = 0 OnClick = btnSvrStartClick end object btnSvrStop: TButton Left = 360 Top = 52 Width = 75 Height = 21 Caption = #20572#27490 Enabled = False TabOrder = 1 OnClick = btnSvrStopClick end object editSvrMsg: TEdit Left = 74 Top = 25 Width = 280 Height = 21 BorderStyle = bsNone Enabled = False TabOrder = 2 end object lbSvrLog: TListBox Left = 74 Top = 52 Width = 280 Height = 69 ItemHeight = 13 TabOrder = 3 end end object GroupBox2: TGroupBox Left = 0 Top = 133 Width = 443 Height = 136 Caption = #23458#25143#26426'(Client)' TabOrder = 1 object Label21: TLabel Left = 8 Top = 27 Width = 60 Height = 13 Caption = #21457#36865#30340#25968#25454 end object Label22: TLabel Left = 44 Top = 46 Width = 24 Height = 13 Caption = #30446#24535 end object editCltMsg: TEdit Left = 74 Top = 24 Width = 280 Height = 21 TabOrder = 0 end object btnConnect: TButton Left = 360 Top = 24 Width = 75 Height = 21 Caption = #36830#25509 TabOrder = 1 OnClick = btnConnectClick end object btnSend: TButton Left = 360 Top = 51 Width = 75 Height = 21 Caption = #21457#36865 Enabled = False TabOrder = 2 OnClick = btnSendClick end object btnDisconnect: TButton Left = 360 Top = 78 Width = 75 Height = 21 Caption = #26029#24320 Enabled = False TabOrder = 3 OnClick = btnDisconnectClick end object lbCltLog: TListBox Left = 74 Top = 51 Width = 280 Height = 78 ItemHeight = 13 TabOrder = 4 end end object btnExit: TButton Left = 360 Top = 283 Width = 75 Height = 21 Caption = #36864#20986 TabOrder = 2 OnClick = btnExitClick end end ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EMail:iqq.em@qq.com QQ:2229198968
|
|