Einzelnen Beitrag anzeigen

Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#1

Übertragungsprotokoll für TSocket ???

  Alt 5. Mär 2010, 12:07
Hallo,

ich habe ein Client-Server-System basierend auf dem TSocket per TCP erstellt.

Delphi-Quellcode:
Socket(AF_INET,
                   SOCK_STREAM,
                   IPProto_TCP);

das problem ist, das alt bekannte.
wie schaffe ich es die daten richtig zu verpacken, sodass der empfänger damit ordentlic harbeiten kann.


ich habe mir ein protokoll ausgedacht, das folgendermaßen aussieht:
(die begriffe Frame und Packet sind nicht auf das OSI modell bezogen)


jeder Frame hat 8192 bytes

zuerst kommt ein header Frame:
er besteht aus
- GlobalID (2Byte) diese beschreibt das Paket, zu welchem mehrere Teile gehören, bei jedem Teilstück ist diese ID gleich
- LocalID (2Byte) diese identifiziert das Teilstück an sich.
- Command (2Byte) ist das auszuführende kommando
- Daten (8186Byte) die ersten teile der daten


dann folgen die Daten Frames:
-GlobalID (2Byte)
-LocalID (2Byte) diese wird bei jedem Frame inkrementiert
-Daten (8188Byte)


der letzte Frame hat die LocalID 1111 1111 1111 1111 (0xFFFF) (erstmal vernachlässigbar für das folgende beispiel)
wodurch das ende des paketes angegeben wird.



so sieht ein beispiel aus wie ich die daten sende:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var st:TFileStream;
    str:string;
    buffer:array[1..8192] of Byte;
begin

st:=TFileStream.Create('C:\Dokumente und Einstellungen\Admin\Eigene Dateien\server\1670478.jpg',fmOpenRead);
st.Position:=0;


str:=#00#01#00#01#00#04+IntToStr(st.Size)+#13#10+'C:\'+#13#10+'pic.jpg'+#13#10; //frameheader und erste daten


Send(FConnectSocket[0],str[1],Length(str),0);
buffer[4]:=$00000;
while st.Position<st.Size do begin
//FillChar(buffer,8192,#0);
buffer[1]:=$0000;
buffer[2]:=$0001;
buffer[3]:=$0000;
buffer[4]:=buffer[4]+$0001;
st.Read(buffer[5],8188);
Send(FConnectSocket[0],buffer[1],Length(buffer),0);
end;
  st.Free;

end;

das funktioniert allerdings nicht ganz.
der server scheint alles richtig zu senden, zumindest steht alles richtig in buffer drin

das problem ist jetzt folgendes:

beim Client kommt der Header Frame richtig an und wird auch korrekt verarbeitet.
ich empfange immer genau 8192 Bytes;

jeder weitere Datenteil der ankommt, hat auch den header dran und wird zum paket hinzugefügt.

allerdings variiert die komplette datengröße
das bild ist 650KB groß und es kommen mal 140KB an, mal 300, mal 640.



so empfange ich per WndProc:
Delphi-Quellcode:
var buffer:string;

FD_READ:
      begin

      setLength(buffer,8192);

        count:=recv(wp,buffer[1],8192,0);
        {setLength(buffer,count);

        packeter(buffer);}


        while count>0 do begin
        setLength(buffer,count);
        packeter(buffer);
        setLength(buffer,8192);
        count:=recv(wp,buffer[1],8192,0);
        end;

        writeln(IntToStr(Length(Packets[0].Data)));

        //writeLn(ntohs(socketaddr.sin_port));
        //OnRead(wp,buffer);
        PostQuitmessage(Msg);
        //-- WMOnAsyncServerData(wp, lp);
     end;



aber nicht das richtige.

was mache ich falsch ?
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat