Borland Socket Service
这段时间,无事可做,拿SocketService的源程序来看,
但是好多不通不懂,望大虾们一起研究研究
分不多,因为我觉得如果研究出来东西,分数是小事。
当然可以加分。
//最重要的处理。每个客户端连入的ServerSocket中,在这里进行同步的处理。
procedure TSocketDispatcherThread.ClientExecute;
var
Data: IDataBlock;
msg: TMsg;
Obj: ISendDataBlock;
Event: THandle;
WaitTime: DWord;
begin
CoInitialize(nil);
try
Synchronize(AddClient);
//Create New Server Socket transport.TSocketTransport.Create;
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;
//当 thread not terminated and FTransport not connected is keepconnection.
//在这里,客户端的要求都在这里进行处理。
while not Terminated and FTransport.Connected do
try
case MsgWaitForMultipleObjects(1, Event, False, WaitTime, QS_ALLEVENTS) of
WAIT_OBJECT_0:
begin
//说明此事件已经处理过了,将其reset nil.
WSAResetEvent(Event);
//接收到 Client port data
Data := FTransport.Receive(False, 0);
if Assigned(Data) then
begin
FLastActivity := Now;
//注1(下面的VCL的处理)
//??????????????处理些什么FInterpreter.InterpretData(Data)
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
//except :Client stop
FTransport.Connected := False;
end;
finally
FInterpreter.Free;
FInterpreter := nil;
end;
finally
FTransport := nil;
end;
finally
CoUninitialize;
Synchronize(RemoveClient);
end;
end;
//这个注1
procedure TDataBlockInterpreter.InterpretData(const Data: IDataBlock);
var
Action: Integer;
begin
Action := Data.Signature;
if (Action and asMask) = asError then DoException(Data);
try
case (Action and asMask) of
asInvoke: DoInvoke(Data);
asGetID: DoGetIDsOfNames(Data);
asCreateObject: DoCreateObject(Data);
asFreeObject: DoFreeObject(Data);
asGetServers: DoGetServerList(Data);
asGetAppServers: DoGetAppServerList(Data);
else
if not DoCustomAction(Action and asMask, Data) then
raise EInterpreterError.CreateResFmt(@SInvalidAction, [Action and asMask]);
end;
except
on E: Exception do
begin
Data.Clear;
WriteVariant(E.Message, Data);
Data.Signature := ResultSig or asError;
FSendDataBlock.Send(Data, False);
end;
end;
end;