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 ?