Czesc,
zaczalem przenosic moj projekt z Delphi na Lazarusa. Problem pojawil sie w momencie obslugi Klientow przez moj serwer, ktory dla kazdego klienta tworzy watek. Czy moglibyscie mi pomoc i podpowiedziec gdzie powinienem zrobic cos inaczej?
Problem pojawia sie w momencie kiedy podlaczeni sa juz nawet 2 klienci, wtedy czasami mam opoznienie w odbiorze pakietu (localhost) nawet ok 1 sekunda.
Korzystam z TLTCPComponent z pakietu INet.
SerwerAccept, pojawia sie nowy Klient:
procedure TForm1.SerwerAccept(aSocket: TLSocket);
var
I:Integer;
tmp:longword;
begin
MLogi.Lines.add('Polaczony Klient'); //zdaje sobie sprawe, ze w kazdym watku takie rzeczy powinno sie robic z Synchronize
I := 0; //szukam wolnego miejsca w tablicy gdzie trzymam sockety
while I < Length(Clnts) do begin
if Clnts[I] = nil then Break;
Inc(I);
end;
if I = Length(Clnts) then SetLength(Clnts, I + 1); //jak nie ma wolnego miejsca to robie nowe
Clnts[I] := aSocket; //przypisuje socket
New(NowyKlient); //przekazuje numer w tablicy do nowego watku
NowyKlient^ := I;
BeginThread(@KlientWatek, Pointer(NowyKlient)); //odpalam nowy watek, ktory bedzie obslugiwal zgloszenia klienta
end;
Wydaje mi sie, ze w powyzszym wszystko jest w miare ok. Problem pewnie pojawia sie w samej funkcji z ktorej tworzony jest nowy watek:
function KlientWatek(Wskaznik: Pointer):Integer;
var
linia:string;
PInt:PInteger;
ok:boolean;
begin
ok:=false;
PInt:=Pinteger(Wskaznik); //biore sobie numer w tablicy ze wskaznika
Form1.MLogi.lines.add(IntTOStr(Pint^)); //wypisuje w memo, ze klient podlaczony - tak jak pisalem, wiem ze tutaj powinno byc przez Synchronize
repeat //i tu pewnie bedzie problem... zaczynam glowna petle watku
case Clnts[Pint^].ConnectionStatus of
scNone: ok:=true;
scDisconnecting: ok:=true;
end;
if ok then Break;
// powyzszy fragment kodu sprawdza stan polaczenia z klientem i jezeli jest jakis problem konczy petle, na koncu zwalnia miejsce w tablicy i konczy watek. W delphi robilem po prostu: Size := recv(Clnts[PInt^], Buff[0], SizeOf(Buff), 0); if Size < 1 then Break;
Clnts[Pint^].GetMessage(linia); //pobieram wiadomosc
if linia<>'' then
Form1.MLogi.Lines.Add(linia); //no i jezeli jakas jest to wypisuje
until false;
Clnts[Pint^].Disconnect(true); //tutaj wywalam socket z tablicy
Clnts[Pint^].Destroy;
Clnts[PInt^] := nil;
Form1.MLogi.Lines.Add('Odchodzi Klient: '+IntToStr(Pint^));
Dispose(PInt);
Result:=0; //koncze watek
EndThread(0);
end;
Mam wrazenie, ze odpalajac np juz 3 klientow serwer sprawia wrazenie zamulonego, pakiety dochodza jakby lekko opoznione. Nie wiem czy to co zrobilem to jest optymalne rozwiazanie. Mozecie mi podpowiedziec czy to jest dobre a moze takie rzeczy rozwiazuje sie w inny sposob?
W Delphi mialem serwer w wersji konsolowej. Czy fakt, ze teraz napisalem to w 'okienkach' ma jakis wplyw na szybkosc dzialania serwera?
pozdrawiam!