![]() |
Übertragungsprotokoll für TSocket ???
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 ? |
Re: Übertragungsprotokoll für TSocket ???
Welche Delphiversion hat du denn?
|
Re: Übertragungsprotokoll für TSocket ???
ich nutze Delphi 7 Enterprise
|
Re: Übertragungsprotokoll für TSocket ???
zur Erinnerung: Das ganze NonVCL!
Sherlock |
Re: Übertragungsprotokoll für TSocket ???
ja das ganze soll auf der client seite nonVCL sein.
der server kann VCL nutzen. deswegen will ich auf der Client seite auch keine Streams nutzen. hab hier mal reingeschaut, ist allerdings sehr unübersichtlich. ![]() und ich hab ma nen chat auf string basis mit terminator geeschrieben. allerdings will ich jetzt daten und befehle, also teilweise Bytes teilweise strings übertragen und für Dateiübertragung brauche ich ja ein anderes verfahren, deshalb diese Variante, fallsihr eine bessere möglichkeit habt das mit TSocket zu realisieren, könnt ihr die gern an bringen. auf jedenfall soll das ganze nonVCL sein und TSocket nutzen. |
Re: Übertragungsprotokoll für TSocket ???
Du musst die Pakete unterschiedlicher Größe sammeln und dann immer schauen, ob eins deiner Frames fertig ist. Das ist dir bewusst (kam jetzt nicht so heraus)?
|
Re: Übertragungsprotokoll für TSocket ???
ähm
kannn sein, dass ich dich falsch verstanden habe, sirius. also in paketer wird der buffer ausgewertet:
Delphi-Quellcode:
Das ist alles hier grad erst mal testweise hingeschrieben, deswegn auch Packets[0] ganz unten,
type TPacket = record
GlobalID:Word; LocalID:Word; CMD:Word; Data:string; end; procedure packeter(buffer:string); var check:boolean; i:integer; begin if Copy(buffer,3,2)=#0#1 then begin setLength(Packets,Length(Packets)+1); Packets[Length(Packets)-1].GlobalID:=Byte(buffer[1])+Byte(buffer[2]); Packets[Length(Packets)-1].LocalID:=Byte(buffer[3])+Byte(buffer[4]); Packets[Length(Packets)-1].CMD:=Byte(buffer[5])+Byte(buffer[6]); Delete(buffer,1,6); Packets[Length(Packets)-1].Data:=buffer; end else begin {check:=false; for i:=0 to Length(Packets)-1 do if Packets[i].GlobalID=Byte(buffer[1])+Byte(buffer[2])then begin check:=true; break; end; Delete(buffer,1,4); if check then} Delete(buffer,1,4); Packets[0].Data:=Packets[0].Data+buffer; end; end; da ich eh erstmal nur ein Packet übertrage, nämlich das fürs bild |
Re: Übertragungsprotokoll für TSocket ???
Ja, aber das Socket zerschneidet dir doch deine Pakete. TCP achtet nur darauf, dass Sie in der richtigen Reihenfolge ankommen.
Was ist, wenn gerade an der Stelle gebrochen wird, wo auch das Bild mit #0#1 weitergeht? Du musst den gesamtn Datenstrom erstmal sammeln:
Delphi-Quellcode:
setlength(tempbuffer,8192);
len:=recv(s,tempbuffer[1],length(tempbuffer),0); setlength(tempbuffer,len); buffer:=buffer+tempbuffer; //analysiere buffer auf fertiges Paket //wenn Paket fertig, bearbeite Paket und lösche so viele Bytes von buffer-Anfang, iwe Paket groß war |
Re: Übertragungsprotokoll für TSocket ???
so
ich habs mal so gemacht und mir die länge ausgeben lassen: Edit: jede zeile steht für eine FM_READ MSG die abgearbeitet wurde. insgesamt sind trotzdem nicht alle daten angekommen. :wall: :mrgreen: 28 8192 16384 8192 0 024576 49152 0 0 32768 65536 8192 0 0 163840 0 0 196608 0 0 0 0 ich versteh nicht warum er nicht gleich alle daten einliest, sondern in unterschiedlichen abständen ne neue MSG macht :gruebel: |
Re: Übertragungsprotokoll für TSocket ???
ich verstehs einfach nicht.
die anzahl der insgesamt empfangenen daten variiert ständig bis zu 100kb. wie kann sowas zustande kommen ??? lese ich den FileStream falsch ein ??? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz