Packed record i Socket'y

0

Witam :-)
Zrobilem komunikator, ktory wysyla pomiedzy sobą informacje poprzez stringi tzn "loginNickHaslo*" jednak chcial bym zamienic komunikacje na wymiane pakietów pomiedzy serwerem a clientem, robie pakiet w ten sposób:

TUser = Packed record
Nick:string[8];
Haslo:string[8];
Msg:string[255];
end;

wzystko jest ok ale....nie moge wyslac Msg wiekszego niz 255 znaków...
a gdy dam.... tak:

TUser = Packed record
Nick:string;
Haslo:string;
Msg:string;
end;

jest ok ale......nie wysyla sie przez gniazdka...prosze o pomoc i z gory dzieki :-) [browar][browar]

0

Bo masz ustawiona opcje kompilatora $h+ ... String wtedy jest wskaznikiem i wysyłasz 4 bajty zamiast tekstu... Lepiej uzyć wtedy shortstringa/stringa[rozmiar<256]. Co do podziału...

function get256ptr(nrpaczki:integer;var dane): pointer;
var p: pointer;
begin
  p:=@dane;
  inc(longword(p),256*nrpaczki); // cardinal, czy inne dword
  get256ptr:=p; // :=pointer(longword(longword(@dane)+nrpaczki*256))
end; 

Ustawiasz wskaźnik na konkretna 256 elementową paczkę, zaczynając od 0.

// rozwiazanie z inkrementacja wskaznika jest całkowicie dobre tylko dla trybu chronionego. Dla trybu rzeczywistego, trzeba pilnować przepełnienia offsetu.

0

Ja polecałbym IdTCPClient zamiast TClientSocket, ale jest trudniejszy w obsłudze.

0

Szymek ale mi chodzi o to ze.....nie potrafie przeslac pakietu w takiej postaci:

TUser = packed record
Nick:string;
Haslo:string;
Msg:string;
end;

tylko da sie przeslac dodając za string np: [255] czyli Nick:String[8]; itd..ale bez tego nie idzie :(:(

0

Wyślij w postaci:

|Naglowek|rozmiar1|string1|rozmiar2|string2|rozmiar3|string3|

0

... chodzi o to ze.....nie potrafie przeslac pakietu w takiej postaci...

Juz napisałem... Tak nie wyslesz, przy {$H+}/{$LONGSTRINGS ON} - domyslnym ustawieniu kompilatora... Wtedy string=ansistring i kazda zmienna tego typu to wskaznik do dynamicznie przydzielanego obszaru. Skoro jest to wskaznik, to wysyłając taki rekord wysyłasz 12 bajtów, które u odbiorcy są tylko śmieciami, bo na drugim kompie na pewno pod tymi adresami nie ma tekstu. Dlatego albo ustaw sobie {$h-}, wtedy string=shortstring, albo w deklaracji użyj string[rozmiar] (rozmiar<256)- to też bedzie shortstring (i to niezaleznie od stanu przełącznika). Shortstring jest statycznym typem danych. Przełącznik $H-/$LONGSTRINGS OFF powoduje, że stringi są traktowane tak jak w pascalu...

Tak wygląda twój rekord w pamieci:
-dla ansistring/string i $H+ (sizeof()=12 - sprawdz, jak nie wierzysz)
4 bajty wskaznik do nick
4 bajty wskaznik do haslo
4 bajty wskaznik do msg

  • dla shortstring/string i $h- (sizeof()=768)
    256 bajtów dla nick
    256 bajtów dla haslo
    256 bajtów dla msg
  • dla string[] niezaleznie od $h (według twojego sposobu; sizeof()=256+18)
    9 bajtow dla nick
    9 bajtow dla haslo
    256 bajtow dla msg

Jesli chcesz wysylac przy $h+, to musisz sobie zapamietac, ze trzeba uzyc length(string) i że pod addr(string[1]) znajduja się dane. Ale lepszym sposobem jest uzycie shortstringa, bo wtedy nie musisz kodowac dodatkowo dlugosci przesylanych danych.

1 użytkowników online, w tym zalogowanych: 0, gości: 1