Senden Sie mehr Daten als, was im Sendepuffer gespeichert werden kann

8

Ich verwende C # -Sockets, um meinen eigenen RTSP-Basisserver zu implementieren (zu Lernzwecken). Ich bin gerade dabei, die Logik für den Server zu schreiben, um den Handshake mit dem Client auszuführen, wenn Medienports bei einer DESCRIBE-Anfrage verhandelt werden.

Die Client-Anwendung wurde nicht von mir geschrieben und ich habe keinen Zugang, um die Software zu aktualisieren. Es handelt sich um einen einfachen RTSP-Client, der Medien-Ports auf einem Cisco-Router aushandelt und Audio an Clients leitet, die damit verbunden sind.

Die Nutzlast, die ich zurücksenden möchte, ist 1024 Bytes und ein 64-Byte-Header, und von dem, was ich von der Überprüfung meiner Client-App sehe, werden nur 400 Bytes zurück zum Client übertragen.

Die Antwort-Payload ist in C # definiert als:

%Vor%

Die antwortende Methode respondToClient ist implementiert als:

%Vor%

Mit SendCallback , um festzustellen, wann das Paket an den Client gesendet wurde:

%Vor%

Warum empfängt meine Client-Anwendung nur 400 Bytes, und wenn ja, wie kann ich sicherstellen, dass mein ganzes Paket gesendet wird (ich verwende TCP)? Ist das ein hartes Limit von C #? Ich habe MSDN konsultiert und konnte keine Informationen finden, um diese Theorie zu unterstützen.

Wenn weitere Details bezüglich der Implementierung meines Servers erforderlich sind, fragen Sie bitte.

BEARBEITEN Hier ist etwas zum Nachdenken, und ich weiß nicht, warum es so passieren würde, wenn jemand mich erleuchten könnte, wäre das großartig ... @ Gregory Ein Beamer schlug in den Kommentaren vor dass EndSend könnte vorzeitig feuern, ist dies eine Möglichkeit? Nach meinem Verständnis dachte ich, dass der asynchrone Callback nur einmal und nur einmal alle Bytes vom Server zum empfangenden Client-Socket gesendet werden würde.

Damit ich feststellen kann, dass das Paket vom Client nicht vollständig empfangen wurde, geben die folgenden Informationen an, dass die Client-Anwendung nur 400 Byte empfangen hat:

Unterstützt von einem Wireshark-Trace von S- & gt; C

UPDATE Nachdem ich zuvor mit @usr gesprochen habe, habe ich weitere Tests durchgeführt und kann nun bestätigen, dass die Client-Anwendung immer nur eine 400 Byte Antwort vom Server erhält. Ich h

%Vor%

^ Dies ist der Protokoll-Trace, der von der Clientanwendung beim Einwählen auf den Server ausgegeben wird. Hier können wir sehen, dass er 1384 Bytes vom Client zurücknimmt, aber sein Verarbeitungspuffer kann nur 400 Bytes speichern. Ich schaute auf ein Protokoll für eine vorhandene Anwendung, die Streaming auf dem gleichen Gerät behandelt, und in der Wireshark-Ablaufverfolgung, anstatt die Header in einem Block zu senden, sendet es mehrere Chunks zurück mit der info [TCP segment of a reassembled PDU] Ich bin mir nicht sicher, was dies bedeutet (Neu bei Netzwerk-Kram), aber ich nehme an, dass es die Server-Nutzlast zerlegt und sie in mehreren Blöcken übergibt und dann auf dem Client wieder zusammenbaut, um die Anfrage zu bearbeiten.

Wie kann ich dieses Verhalten in meiner Serveranwendung replizieren? Ich versuchte folgendes in meiner Antwort-Methode, mit der Hoffnung, dass es das Paket zurückleitet und auf dem Client wieder zusammenbaut, aber ich fuhr fort, den gleichen Fehler zu bekommen, der oben besprochen wurde:

%Vor%     
Alex 30.06.2015, 16:30
quelle

3 Antworten

2

Das mag umstritten erscheinen, aber der Fehler im Code war extrem albern und ich muss den Erfolg dieser Frage @ Keyz182 in den Antworten zuordnen. Nachdem ich mich privat besprochen hatte, bemerkte er, dass ich \n verwendete, um neue Linienelemente hinzuzufügen.

Das Problem war, dass ich diese Rückgabewerte in \r\n ändern und einen zwischen dem Header und dem Body hinzufügen musste, um dem Client zu diktieren, wo der Header endete und die Body-Informationen der Payload gestartet wurden (Kopf gegen Ziegelwand).

Es stellt sich heraus, dass es auf dem Client keinen 400-Byte-Puffer gab (daher bin ich immer noch amüsiert, warum er über einen Verarbeitungspuffer von 400 Bytes gesprochen hat). Vielen Dank für Ihre Hilfe!

    
Alex 07.07.2015, 21:45
quelle
2

TCP ist ein grenzenloser Bytestrom. Für Anwendungen sind keine Pakete wahrnehmbar. Lese- / Empfangsaufrufe geben eine beliebige Anzahl von Bytes auf nichtdeterministische Weise zurück (mindestens eins). Im Empfänger muss man sich damit auseinandersetzen, dass das Lesen teilweise sein kann. Verwenden Sie den Rückgabewert von Receive, um die Anzahl der empfangenen Bytes zu ermitteln.

Das ist alles einfacher, wenn Sie synchron lesen und BinaryReader verwenden, weil es diese Schleifenlogik für Sie erledigt.

  

BeginSend könnte vorzeitig feuern, ist das eine Möglichkeit

Nein.

    
usr 01.07.2015 10:24
quelle
2

Eine mögliche Antwort könnte sein, dass der Client eine bestimmte Blockgröße in seiner Anfrage an Ihren Server gesetzt hat (siehe 12.7 - Ссылка ). Das kann oder kann nicht anwendbar sein, aber wenn Sie die Anforderung, die der Client Ihnen sendet, auslagern und einen Blick darauf werfen können, sehen Sie möglicherweise eine Blockgröße irgendwo um die 400-Marke.

BEARBEITEN: Prüfe Alex 'Antwort unten für die endgültige Antwort.

    
Keyz182 07.07.2015 18:25
quelle

Tags und Links