程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 類TListenSocket(我寫的類似BorlandSocketService的類)

類TListenSocket(我寫的類似BorlandSocketService的類)

編輯:Delphi

{這是我根據Borland Socket Service改寫的類:TListenSocket, 它的功能是相當於:"X:Program FilesBorlandDelphi5Binscktsrvr.exe"。也是說它可以將你的分布式服務端程序變成一個有偵聽功能的程序,有偵聽,還有你的Remote DataModule可以照樣運行。寫出來不久,如果有什麼BUG,請指出,謝謝。}

{本想把它做成控件方式的,現在不想去改動了。有需要再說,}

{

用法:

uses Listensocket;

var Socket:TListenSocket;

const ListenPort=8888;

Socket:=TListenSocket.Create(Self);

Socket.ListenPort:=ListPort;

Socket.Open;

//OK

}

unit ListenSocket;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  SConnect,ScktComp,SvcMgr, ActiveX,MidConst,winsock,MyConst;

var 
    FClientThreads:TList;
type
  TSocketDispatcherThread = class(TServerClientThread, ISendDataBlock)
  private
    FRefCount: Integer;
    FInterpreter: TDataBlockInterpreter;
    FTransport: ITransport;
    FLastActivity: TDateTime;
    FTimeout: TDateTime;
    FRegisteredOnly: Boolean;
    procedure AddClient;
    procedure RemoveClient;
  protected
    function CreateServerTransport: ITransport; virtual;
   { procedure AddClient;
    procedure RemoveClient; }
    { IUnknown }
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
    { ISendDataBlock }
    function Send(const Data: IDataBlock; WaitForResult: Boolean): IDataBlock; stdcall;
  public
    constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket;
      const InterceptGUID: string; Timeout: Integer; RegisteredOnly: Boolean);
    procedure ClientExecute; override;
  end;

type MyServerSocket=Class(TServerSocket)
  private
    procedure GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;var SocketThread: TServerClientThread);
  public
    constructor Create(AOwner: TComponent); override;
end;

type
  TListenSocket = class(TObject)
  private
    FActive:Boolean;
    FListPort :integer;
    FCacheSize :integer;
    SH:MyServerSocket;
    FItemIndex :integer;
    procedure SetActiveState(Value:boolean);
    function GetClientCount :integer;
    { Private declarations }
  public
    property CacheSize :integer read FCacheSize write FCacheSize;
    property ListPort:integer read FListPort write FListPort;
    property Active :boolean read FActive write SetActiveState;
    property ClientCount:integer read GetClientCount;
  public
    constructor Create(AOwner :TComponent);
    destructor Destroy;override;
    class procedure AddClientThread(Thread :TSocketDispatcherThread);
    class procedure RemoveClientThread(Thread:TSocketDispatcherThread);
    procedure Open;
    procedure Close;
  end;

implementation

function TListenSocket.GetClientCount :integer;
begin
  Result:=FClientThreads.Count;
end;

constructor TListenSocket.Create(AOwner :TComponent);
begin
  LoadWinSock2;
  FActive:=False;
  FClientCount:=0;
  FCacheSize :=10;
  FClientThreads:=TList.Create;
  SH:=MyServerSocket.Create(nil);
  inherited Create;
end;

destructor TListenSocket.Destroy;
begin
  SetActiveState(False);
  FreeAndNil(FClientThreahs);
  inherited Destroy;
end;

procedure TListenSocket.Open;
begin
  SetActiveState(True);
end;

procedure TListenSocket.Close;
begin
  SetActiveState(False);
end;

class procedure TListenSocket.AddClientThread(Thread :TSocketDispatcherThread);
begin
  FClientThreads.Add(Thread);
end;

class procedure TListenSocket.RemoveClientThread(Thread :TSocketDispatcherThread);
var i:integer;
begin
  for i:=0 to FClientThreads.Count -1 do
  begin

    i:=FClientThreahs.IndexOf(Thread);
    if i<>-1then
      FClientThreads.Delete(i);
  end;
end;

procedure TListenSocket.SetActiveState(Value:boolean);
var i:integer;
begin
  if Value then
  begin
    SH.Close;
    SH.Port :=ListPort;
    SH.ThreadCacheSize :=CacheSize;
    SH.Open;
  end else
  if not Value then//if FClientCount>0 then Error(還有客戶在連接狀態,中止。)
    SH.Close;
  FActive:=Value;
end;

//下面的東西都是在Delphi中Copy過來的,為我所用了。呵呵

{MyServerSocket Class}
procedure MyServerSocket.GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
  var SocketThread: TServerClientThread);
begin
  SocketThread:=TSocketDispatcherThread.Create(false,ClientSocket,,0,false);
end;

constructor MyServerSocket.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ServerType := stThreadBlocking;
  OnGetThread := GetThread;
end;
{MyServerSocket Class over}

{TSocketDispatcherThread class}
function TSocketDispatcherThread.CreateServerTransport: ITransport;
var
  SocketTransport: TSocketTransport;
begin
  SocketTransport := TSocketTransport.Create;
  SocketTransport.Socket := ClientSocket;
  Result := SocketTransport as ITransport;
end;

constructor TSocketDispatcherThread.Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket;
      const InterceptGUID: string; Timeout: Integer; RegisteredOnly: Boolean);
begin
  FTimeout:=EncodeTime(Timeout div 60, Timeout mod 60, 0, 0);
  FRegisteredOnly:=RegisteredOnly;
  FLastActivity:=Now;
  inherited Create(CreateSuspended, ASocket);
end;

function TSocketDispatcherThread.Send(const Data:IDataBlock; WaitForResult:Boolean):IDataBlock;
begin
  FTransport.Send(Data);
  if WaitForResult then
    while True do
    begin
      Result := FTransport.Receive(True, 0);
      if Result = nil then break;
      if (Result.Signature and ResultSig) = Resul

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved