Laden...

Fragen zu Sockets / Übertragung

Erstellt von wiesi vor 16 Jahren Letzter Beitrag vor 16 Jahren 3.496 Views
wiesi Themenstarter:in
89 Beiträge seit 2005
vor 16 Jahren
Fragen zu Sockets / Übertragung

Hi,

ich versuche gerade, eine Datei (Binär) über Sockets zu übertragen.
Dabei stellen sich mir folgende Fragen:

  1. Ich lese server-seitig eine Datei ein, z.B. 5672341 bytes. Laut Debugger
    hat mein byte[] auch die richtige Größe. Mit Socket.Send übertrage ich dann
    die Bytes, eingepackt in 1024 bytes großen Paketen. Jetzt kommen beim
    Client aber ca. 500 bytes mehr an, als eigentlich die Datei groß ist. Ich habe
    meinen Empfangspuffer nun mal auf 5672341 eingestellt. Die Datei wird
    korrekt übertragen (binär identisch). Woher kommt also der Rest, zumal dieser
    bei jeder Übertragung auch noch anders (in Größe und Inhalt) ist.

  2. Woher erkenne ich, daß meine Nachricht nun zu Ende ist, welche Bytes
    sind die Terminierung?

  3. Gibt´s für Socket.Send auch so eine Art Flush? Wenn ich innerhalb einer
    Funktion direkt hintereinander die Send-Methode aufrufe, werden diese nicht
    als Einzelnachrichten abgesendet, sondern werden in die vorherige Nachricht
    mit reingepackt, sofern da noch Platz ist.

Wäre super wenn mir jemand die Fragen beantworten könnte ...

Danke und Grüße,
wiesi

45 Beiträge seit 2006
vor 16 Jahren

Servus,

ich vermute, dass die zusätzlichen Bytes von den Paketen selbst stammen. Du hast ja bei TCP/IP nicht nur Nutzdaten, sondern es werden auch Protokolldaten, Header und Checksummen gesendet.

Grüße Taggert

T
56 Beiträge seit 2006
vor 16 Jahren

Moin
Ich denk mal dass es daran liegt:
5672341 /1024 = 5539,39550...
also brauchst du 5540 Packte a 1024 bytes um die Datei zu senden
5540*1024 = 5672960 Bytes

5672960 - 5672341 = 619

Du musstest also 619 bytes zusätzlich empfangen da das letzte 1024 bytes Packet nicht komplett mit den bytes aus der datei befüllt ist. wenn dir am anfang die grösse der datei überträgst kannst es damit dann abfangen, also du sagst dem client als erstes wie gross die datei denn sein wird.

wie gesagt ich denk mal dass es daran liegt, wenns ned stimmt bitte berichtigen
servus

F
35 Beiträge seit 2008
vor 16 Jahren

Hallo,

bitte zeige mir deinen Empfangs, sowie Sendevorgang
(Socket.Receive, Socket.Send);

danke!

Mit freundlichem Gruß

Fabian Stern

info@smart-coding.com
www.smart-coding.com

T
56 Beiträge seit 2006
vor 16 Jahren

Sorry mein Pc is grad am Arsch... ich werde den Code dann posten wenn er wieder geht.

Server:
Zuerst Dateigrösse in Byte[] umwandeln und an den Client schicken


while (readBytes < file.Length)
                            {
                                //Auslesen der Bytes aus Datei
                                length = m_FileStream.Read(this.m_bDataBuffer, 0, this.m_bDataBuffer.Length);
                                //Senden der Bytes an Client
                                this.m_soClientSocket.Send(this.m_bDataBuffer, length, SocketFlags.None);
                                Array.Clear(this.m_bDataBuffer, 0, this.m_bDataBuffer.Length);
                                readBytes = readBytes + length;
                            }


Client:
Dateigröße empfangen und Datei anlegen


lenght = 0;
while (readBytes < fileSize)
                    {
                        //Auslesen der Datenbytes aus dem Strem
                        length = this.m_soClientSocket.Receive(this.m_bDataBuffer, this.m_bDataBuffer.Length, SocketFlags.None);
                        //Schreiben in Datei
                        m_FileStream.Write(this.m_bDataBuffer, 0, length);
                        Array.Clear(this.m_bDataBuffer, 0, this.m_bDataBuffer.Length);
                        readBytes = readBytes + length;
                    }


52 Beiträge seit 2007
vor 16 Jahren
BeginSend()

Wenn Du große Dateien versenden willst dann benutze doch die asynchrone Send Funktion. Die payload Größe ist ja nicht unendlich groß. Kannst auch alles auf einmal senden, allerdings musst Du nach einem Send() überprüfen wieviele bytes tatsächlich gesendet wurden. Dann den offset zu Deinem Sendepuffer verschieben und so lange senden bis alles weg ist.

Eine TCP/IP Verbindung ist ein stream. Du fragst nach der Ende-Kennung für den Server? Schau Dir mal z. B. POP3 an, dort gibt es etwa CRLF.CRLF, allerdings als Ende-Kennung für den Client. Nun Du kannst auch "ja-ist-denn-heut-schon-weihnachten?" als Ende-Kennung definieren, oder Du sendest die Länge in einem header voraus (siehe HTTP Content-length).

yb~~~~~~~~~~~~

S
10 Beiträge seit 2008
vor 16 Jahren

Du musst beim Empfänger nur die "Reste wegschneide.

Du Empfängst das ganze Datenfeld des TCP Packetes, egal ob du nun in 1024Byte oder 2Byte Schritten deine "Datenblocks" verschickst. Der TCP/IP Header ist ja so in etwa 1500KB lang. Ziehst die Headerinformationen (20Bytes glaub ich) ab und du hast die Datenlänge........

Hab das ganze mal mit WireShark getestet......eigentlich ganz einfach.

Beim Empfänger schneidest du die überresten ab (durch den "int" return der Receive Methode, hast du die Datenlänge..nachstehende Felder sind 0)

Noch einfacher wäre die Übertragung mit einem "Networkstream" (ich habs so gelöst)

Zur Kontrolle der Datenübertragung hab ich mir noch einen Header gebastelt, damit vor der Übertragung der MD5-Wert der zu sendenden Datei beim Empfänger hinterlegt ist = MD5-String vergleich 😁 ))

Gruss
stephan