Zatem tak:
Na formie wrzucilem TClientSocket ten z delphi 7 co sie doinstalowuje z paczki wiec sadze ze to takie standardowe. Pierwsza z funkcji jest jedna ze znalezionych na 4p, i wyglada ona tak:
Kopiuj
const
SOI = SizeOf(Integer);
SOW = SizeOf(Word);
SOB = SizeOf(Byte);
procedure Rvrs(var Buf; Count: Integer);
var
S: String;
I: Integer;
begin
SetLength(S ,count);
Move(Buf, Pointer(S)^, Count);
for I := 0 to Count - 1 do
Begin
(PChar(@Buf) + I)^ := S[Count - I];
End;
end;
Jesli zastosuje taki kod:
Kopiuj
I := MainForm.ClientSocket.Socket.ReceiveBuf(SoPck, SOI);
Rvrs(SoPck, SOI);
Memo2.Lines.Add(IntToStr(SoPck));
Result := (I = SOI) and (SoPck >= SOI + (2 * SOW));
if not Result then Exit;
Memo3.Lines.Add('Dlugosc Pakietu start: ' + inttostr(SoPck) );
Chodzi o to ze pobieram pierwsze 4 bajty [Socket.ReceiveBuf(SoPck, SOI);]
Po funkcji [Rvrs(SoPck, SOI);] w zmiennej SoPck mam wynik 410
Nastepnie program dalej rozpakowuje pakiet, pobiera sobie kolejne 2 bajty
odczytuje z nich dane i pobiera kolejne 2 bajty itd. Ale w tym zalozeniu
jest blad poniewaz zalozylem ze pakiet jaki przychodzi to przychodzi jednym odczytem
a moze sie zdarzyć, dostane kawalek pakietu. Dlatego chcialem uzyc funkcji skladajacej
pakiet do jakiegos dynamicznego przejsciowego bufora:
Poniewaz nie mam w socketach funkcji PEEK DATA czyli nie moge sprawdzic ile juz przyszlo
danych chcialem uzyc innego socketa ale nie znalalem nic. Dlatego algorytm jest taki:
- pobierz 4 bajty z pakietu ktory przyjdzie:
- Odczytaj jaka jest dlugosc pakietu (np dl = 410)
- W tej dlugosci jest zawarta dlugosc tych 4 bajtow wiec odejmujemy 4 bajty to dl = 410 - 4 = 406
- Teraz chcialem zeby program odczytal [Socket.ReceiveBuf(SoPck, 406);]
- Sprawdz ile przyszlo:
a) jesli przyszlo mniej niz oczekiwane 406 to wstaw to co odczytales do bufora tymczasowego.
Odczytaj ile juz przyszlo i odejmij od 406 to co przyszlo np:206 (406 - 206 = 200)
wroc do punktu 4 ale odczytaj 200 bajtow
b) Jesli przyszlo tyle co oczekiwalismy wstaw do bufora przejsciowego i wroc do punktu 1
ten bufor przejsciowy to maja byc tam juz odberane pakiety czekajace na pobranie i
rozpakowanie ich wedlug kodu ktory tez juz jest zrobiony i dziala w przypadku jesli zalozenie
to bledne jest prawdziwe. Jesli pakiet jest mniejszy wtedy odczytuje jakies syfy i program wywala
access violation czyli wiadomo ze probowal dostac sie tam gdzie nie trzeba :)
I teraz kod rozpakowujacy pakiet jest w ON READ Socket a tak moze by co sekunda dac ten kod w timerze zeby sprawdzal czy sa jakies pakiety i jesli sa niech bierze pierwszy z kolejki i zmniejsza bufor o jego wielkosc. a funkcja dodajaca pakiet niech zwieksza go o dana wielkosc pakietu. W ten sposob dynamicznie bedziemy ustawiac bufor tymczasowy ktory nigdy sie nie przepelni....
Ale nie wiem czy to dobre rozwiazanie, robie juz z miesiac ponad to i nadal nie dziala jak powinno. :(