Zrobiłem taką procedurę. Działa poprawnie, rozdziela komunikaty od serwera nawet jeżeli przylecą sklejone w jednym sockecie. Jeżeli jakiś został rozdzielony to również go skleja. Na pewno można to zapisać o wiele prościej ale już dzisiaj późno i stać mnie było tylko na takie coś ;)
Kiedy przychodzą pakiety to wrzucam je do "Bufor", który jest typu TStringList. Zabezpieczam to wszystko TCriticalSection.
Dodalem wiecej komentarzy zeby latwo bylo sie zorientowac o co chodzi.
procedure TObslugaBufora.Execute;
var
stop,P,K:integer;
socket, komunikat, urwany:string;
koniec:boolean;
begin
stop:=0; //na potrzeby nieskonczonej petli, ktora sprawdza bufor
urwany:=''; //tu bedzie trzymany fragment urwanego komunikatu
repeat //zaczynamy nieskonczona petle
socket:=''; //zerujemy przed pobranie z bufora
CSBufor.Enter;
if Bufor.Count>0 then
begin
socket:=Bufor[0]; //pobieramy z bufora i wyrzucamy z niego pobrany socket
Bufor.Delete(0);
end;
CSBufor.Leave;
if socket<>'' then //jezeli cos jest w buforze...
begin
repeat //obrabiamy socket az wydzielimy wszystkie komunikaty
koniec:=false; //jezeli zakonczymy prace nad socketem
//kazdy komunikat zaczyna sie znakiem <
//a konczy > np. <test1|test2|test3|test4>
if urwany<>'' then //poprzedni socket konczyl sie urwanym komunikatem
begin
K:=AnsiPos('>', socket);
komunikat:=Copy(socket, 1, K);
urwany:=urwany+komunikat;
Delete(socket, 1, K);
Przekaz(urwany); //docinamy brakujacy fragment i przekazujemy do wlasciwej obrobki
urwany:='';
end;
P:=AnsiPos('<', socket);
K:=AnsiPos('>', socket);
if (P<>0)and(K<>0) then //jezeli znaleziono kolejny komunikat
begin
komunikat:=Copy(socket, P, K);
Delete(socket, P, K);
Przekaz(komunikat); //docinamy i przekazujemy do obrobki
end //znalezlismy juz wszystkie pary w sockecie
else
begin
koniec:=true;
end;
if (P<>0) and (K=0) then //jezeli ostatnia para jest urwana
begin
urwany:=socket; //reszta, ktora zostala z socketa, zostanie doklejona przy nastepnym sockecie
koniec:=true;
end;
until koniec; //koniec obrobki socketu
end;
Sleep(50); //chwile spimy
until stop=1; //nieskonczona petla
end;
A dziala to tak:
Dane wejsciowe:
Socket1:
<test0|test2|test3|test4|test5|test6><test1|test2|test3|test4|test5|test6><test2|test2|test3|test4|test5|test6><test3|test2|test3|test4|test5|test6><test4|test2|test3|test4|test5|test6><test5|test2|test3|test4|test5|test6><test6|test2|test3|test4|test5|test6><test7|test2|test
Socket2:
3|test4|test5|test6><test8|test2|test3|test4|test5|test6><test9|test2|test3|test4|test5|test6><test10|test2|test3|test4|test5|test6><test11|test2|test3|test4|test5|test6><test1
Socket3
2|test2|test3|test4|test5|test6>
Dane wyjsciowe:
<test0|test2|test3|test4|test5|test6>
<test1|test2|test3|test4|test5|test6>
<test2|test2|test3|test4|test5|test6>
<test3|test2|test3|test4|test5|test6>
<test4|test2|test3|test4|test5|test6>
<test5|test2|test3|test4|test5|test6>
<test6|test2|test3|test4|test5|test6>
<test7|test2|test3|test4|test5|test6>
<test8|test2|test3|test4|test5|test6>
<test9|test2|test3|test4|test5|test6>
<test10|test2|test3|test4|test5|test6>
<test11|test2|test3|test4|test5|test6>
<test12|test2|test3|test4|test5|test6>