分享

套接字(Socket)编程的基本方法(供初学者参考)

 昵称7800307 2011-09-27
 
套接字(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
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EMailiqq.em@qq.com QQ:2229198968

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多