Mój program to serwer pośredniczący pomiędzy klientem i właściwym serwerem. Dla każdego połączenia przychodzącego tworzony jest wątek SockThread. SockThread tworzy TClientSocket do połączenia się z właściwym serwerem.
@b0bik: Przerzucenie danych do OnConnect nic mi nie dało. SockThread jest zamrożony (czeka na dane przez recv) a TClientSocket podejmuje próbę połączenia się dopiero po wykonaniu całej procedury SockThread. Jeśli ktoś ma jeszcze jakiś pomysł to byłbym wdzięczny :-) Jeśli jedynym jedynym wyjściem/lepszym wyjściem jest użycie TClientSocket-Blocking to prosiłbym o jakiś przykład użycia/tutorial bo nie mogę go doprowadzić do "używalności" (zamraża mi się i nie odczytuje danych przychodzących od serwera [???] )
type
PInteger = ^Integer;
type
TEventHandlers = class // create a dummy class
procedure Odebranie(Sender: TObject; Socket: TCustomWinSocket);
procedure Polaczenie(Sender: TObject; Socket: TCustomWinSocket);
procedure Rozlaczenie(Sender: TObject; Socket: TCustomWinSocket);
end;
TBuffStack=record
Buff:array[0..1023] of byte;
len:integer;
end;
TProx=record
ServSock:TSocket;
CS:TClientSocket;
connStart:Cardinal;
dataStos:array of TBuffStack;
end;
var
Sock: TSocket;
PInt: PInteger;
Clnts: Array of TProx;
EvHandler:TEventHandlers;
procedure SockThread(Pint: PInteger); stdcall;
var
Size, I,k,a: Integer;
Buff: Array[0..1023] of Byte;
TMP:Dword;
begin
Clnts[PInt^].CS:=TClientSocket.Create(form1);
Clnts[PInt^].CS.OnConnect:=EvHandler.Polaczenie;
Clnts[PInt^].CS.OnDisconnect:=EvHandler.Rozlaczenie;
Clnts[PInt^].CS.OnRead:=EvHandler.Odebranie;
//Clnts[PInt^].CS.ClientType:=ctBlocking;
Clnts[PInt^].CS.Host:=LOGIN_IP1;
Clnts[PInt^].CS.Port:=7171;
Clnts[PInt^].CS.Active:=true;
repeat
Size:=recv(Clnts[PInt^].ServSock, Buff[0], 1024, 0);
form1.logmem.Lines.Add('[S]Recived '+inttostr(size)+' from '+inttostr(Clnts[PInt^].ServSock));
if Size < 1 then Begin
if Clnts[PInt^].CS.Active=true then Clnts[PInt^].CS.Active:=false;
Break;
End;
if Clnts[PInt^].CS.Active=true then Begin
Clnts[PInt^].CS.Socket.SendBuf(Buff[0],Size);
form1.logmem.Lines.Add('[S]Forwarded '+inttostr(size)+' to '+inttostr(Clnts[PInt^].CS.Socket.SocketHandle));
end else begin
SetLength(Clnts[PInt^].dataStos,High(Clnts[PInt^].dataStos)+2);
for a:=0 to 1023 do
Clnts[PInt^].dataStos[High(Clnts[PInt^].dataStos)].Buff[a]:=Buff[a];
Clnts[PInt^].dataStos[High(Clnts[PInt^].dataStos)].len:=Size;
form1.logmem.Lines.Add('Added '+inttostr(size)+' bytes on stack');
end;
//RecivePacket(Clnts[PInt^], NetMsg, PlayerID);
until false;
if Clnts[PInt^].CS.Active=true then Clnts[PInt^].CS.Active:=false;
Clnts[PInt^].CS.Destroy;
shutdown(Clnts[PInt^].ServSock, SD_BOTH);
closesocket(Clnts[PInt^].ServSock);
Clnts[PInt^].ServSock := INVALID_SOCKET;
Dispose(PInt);
end;
procedure TEventHandlers.Odebranie(Sender: TObject; Socket: TCustomWinSocket);
var
size:integer;
Buff: Array[0..1023] of Byte;
begin
Size:=Socket.ReceiveBuf(Buff[0], 1024);
form1.logmem.Lines.Add('[C]Recived '+inttostr(size)+' from '+inttostr(Socket.SocketHandle));
//do zrobienia kod na przesylanie danych do klienta
end;
procedure TEventHandlers.Polaczenie(Sender: TObject; Socket: TCustomWinSocket);
var a,b:integer;
begin
form1.logmem.Lines.Add('[S]Connected to login server in '+inttostr(Socket.SocketHandle));
for a:=0 to high(Clnts) do begin
if Clnts[a].CS.Socket.SocketHandle=Socket.SocketHandle then Break;
end;
for b:=0 to High(Clnts[a].dataStos) do Begin
Socket.SendBuf(Clnts[a].dataStos[b].Buff,Clnts[a].dataStos[b].len);
End;
form1.logmem.Lines.Add('[S]Sent '+inttostr(High(Clnts[a].dataStos))+' stacked buffs');
end;
procedure TEventHandlers.Rozlaczenie(Sender: TObject; Socket: TCustomWinSocket);
begin
form1.logmem.Lines.Add('[S]Disconnected from login server in '+inttostr(Socket.SocketHandle));
end;
Procedure MainSockThread;
var
i:integer;
Tmp: DWord;
AdrR: TSockAddrIn;
Begin
repeat
I := 0;
while I < Length(Clnts) do begin
if Clnts[I].ServSock = INVALID_SOCKET then Break;
Inc(I);
end;
if I = Length(Clnts) then SetLength(Clnts, I + 1);
Tmp := SizeOf(AdrR);
Clnts[I].ServSock := accept(Sock, @AdrR, @Tmp);
if Clnts[I].ServSock = INVALID_SOCKET then Break;
New(PInt);
PInt^ := I;
CreateThread(nil, 0, @SockThread, PInt, 0, Tmp);
until False;
form1.logmem.Lines.Add('Serwer zatrzymany.');
WSACleanUp();
End;