分享
 
 
 

类TListenSocket(我写的类似Borland Socket Service的类)

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

{这是我根据Borland Socket Service改写的类:TListenSocket, 它的功能是相当于:"X:\Program Files\Borland\Delphi5\Bin\scktsrvr.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) = ResultSig then

break else

FInterpreter.InterpretData(Result);

end;

end;

procedure TSocketDispatcherThread.AddClient;

begin

TListenSocket.AddClientThread(Self);

end;

procedure TSocketDispatcherThread.RemoveClient;

begin

TListenSocket.RemoveClientThread(Self);

end;

procedure TSocketDispatcherThread.ClientExecute;

var

Data: IDataBlock;

msg: TMsg;

Obj: ISendDataBlock;

Event: THandle;

WaitTime: DWord;

begin

CoInitialize(nil);

try

Synchronize(AddClient);

FTransport := CreateServerTransport;

try

Event := FTransport.GetWaitEvent;

PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);

GetInterface(ISendDataBlock, Obj);

if FRegisteredOnly then

FInterpreter := TDataBlockInterpreter.Create(Obj, SSockets) else

FInterpreter := TDataBlockInterpreter.Create(Obj, '');

try

Obj := nil;

if FTimeout = 0 then

WaitTime := INFINITE else

WaitTime := 60000; //MAXIMUM_WAIT_OBJECTS

while not Terminated and FTransport.Connected do

try

case MsgWaitForMultipleObjects(1, Event, False, WaitTime, QS_ALLEVENTS) of

WAIT_OBJECT_0:

begin

WSAResetEvent(Event);

Data := FTransport.Receive(False, 0);

if Assigned(Data) then

begin

FLastActivity := Now;

FInterpreter.InterpretData(Data);

Data := nil;

FLastActivity := Now;

end;

end;

WAIT_OBJECT_0 + 1:

while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do

DispatchMessage(msg);

WAIT_TIMEOUT:

if (FTimeout > 0) and ((Now - FLastActivity) > FTimeout) then

FTransport.Connected := False;

end;

except

FTransport.Connected := False;

end;

finally

FInterpreter.Free;

FInterpreter := nil;

end;

finally

FTransport := nil;

end;

finally

CoUninitialize;

Synchronize(RemoveClient);

end;

end;

function TSocketDispatcherThread.QueryInterface(const IID: TGUID; out Obj): HResult;

begin

if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;

end;

function TSocketDispatcherThread._AddRef: Integer;

begin

Inc(FRefCount);

Result := FRefCount;

end;

function TSocketDispatcherThread._Release: Integer;

begin

Dec(FRefCount);

Result := FRefCount;

end;

{TSocketDispatcherThread class over}

end.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有