Finden Sie heraus, ob eine Nachricht über TCP zugestellt wurde

Lesezeit: 4 Minuten

Benutzeravatar von user185582
Benutzer185582

Wie kann ich beim Senden()/Schreiben() einer Nachricht über einen TCP-Stream herausfinden, ob diese Bytes erfolgreich übermittelt wurden?

Der Empfänger bestätigt den Empfang der Bytes über TCP, daher sollte der TCP-Stack des Absenders Bescheid wissen.

Aber wenn ich einige Bytes send() sende, kehrt send() sofort zurück, auch wenn das Paket (noch) nicht zugestellt werden konnte. Ich habe das unter Linux 2.6.30 mit Strace auf Netcat getestet und mein Netzwerkkabel herausgezogen, bevor ich einige Bytes gesendet habe.

Ich entwickle gerade eine Anwendung, bei der es sehr wichtig ist zu wissen, ob eine Nachricht zugestellt wurde, aber die Implementierung von TCP-Funktionen („Bestätigung für Nachricht Nr. 123“) fühlt sich umständlich an, es muss einen besseren Weg geben.

Benutzeravatar des Cafés
Café

Der sendende TCP weiß zwar, wann die Daten vom anderen Ende bestätigt werden, aber der einzige Grund, warum er dies tut, besteht darin, dass er weiß, wann er die Daten verwerfen kann (da nun jemand anderes dafür verantwortlich ist, sie an die Anwendung auf der anderen Seite zu übermitteln). ).

Normalerweise werden diese Informationen nicht an die sendende Anwendung weitergegeben, da dies (entgegen dem Anschein) tatsächlich nicht der Fall wäre bedeuten Viel zur absendenden Bewerbung. Die Bestätigung bedeutet nicht, dass die empfangende Anwendung die Daten erhalten und etwas Vernünftiges damit gemacht hat – sie bedeutet lediglich, dass sich der sendende TCP nicht mehr darum kümmern muss. Die Daten könnten sich noch in der Übertragung befinden – beispielsweise innerhalb eines zwischengeschalteten Proxyservers oder innerhalb des empfangenden TCP-Stacks.

„Daten erfolgreich empfangen“ ist eigentlich ein Konzept auf Anwendungsebene – was es bedeutet, variiert je nach Anwendung (beispielsweise wäre es bei vielen Anwendungen erst dann sinnvoll, die Daten als „empfangen“ zu betrachten, wenn sie auf der Festplatte des Empfängers synchronisiert wurden). Seite). Das bedeutet also, dass Sie es selbst umsetzen müssen, denn als Anwendungsentwickler sind Sie eigentlich der Einzige, der weiß, wie man es für Ihre Anwendung sinnvoll umsetzt.

Paul Tomblins Benutzeravatar
Paul Tomblin

Der beste Weg ist, den Empfänger eine Bestätigung zurücksenden zu lassen, auch wenn es sich „unangenehm“ anfühlt. Denken Sie daran, dass IP Ihre Daten möglicherweise in mehrere Pakete aufteilt und diese wieder zusammensetzt. Dies kann während einer Übertragung mehrmals erfolgen, wenn verschiedene Router auf dem Weg unterschiedliche MTUs haben, sodass Ihr Konzept von „einem Paket“ und TCPs möglicherweise nicht übereinstimmen.

Es ist weitaus besser, Ihr „Paket“ zu senden, egal ob es sich um eine Zeichenfolge, ein serialisiertes Objekt oder binäre Daten handelt, und den Empfänger alle nötigen Prüfungen durchführen zu lassen, um sicherzustellen, dass es da ist, und dann eine Bestätigung zurückzusenden.

  • Die Fakten stimmen, aber mir gefällt die Formulierung nicht. TCP ist ein zuverlässiges Protokoll, Sie Wille Hören Sie davon, wenn die Übertragung fehlschlägt. Die Tatsache, dass Sie kein ACK von der Remote-Seite anfordern müssen, ist eine Funktion und kein Fehler. Der „beste“ Weg, damit umzugehen, ist ignorieren Das Problem liegt auf der Ebene der Systemaufrufe und Bytes. Wenn Sie ein Ergebnis zurück benötigen, tun Sie dies auf der Ebene des Protokolls, nicht auf der Ebene der Sockets.

    – Andy Ross

    8. Okt. 2009 um 18:28

Das TCP-Protokoll ist sehr bemüht, sicherzustellen, dass Ihre Daten ankommen. Wenn ein Netzwerkproblem vorliegt, werden die Daten einige Male erneut übertragen. Das bedeutet, dass alles, was Sie senden, gepuffert wird und es keine rechtzeitige Möglichkeit gibt, sicherzustellen, dass es angekommen ist (bei einem Netzwerkausfall kommt es 2 Minuten später zu einer Zeitüberschreitung).

Wenn Sie eine schnelle Rückmeldung benötigen, nutzen Sie das UDP-Protokoll. Es verbraucht keinen TCP-Overhead, aber Sie müssen alle Probleme selbst lösen.

  • Ja, vom Design her ist es zuverlässig und geordnet

    – RichardOD

    7. Oktober 2009 um 13:18

Selbst wenn es bis zur TCP-Ebene gelangte, gibt es keine Garantie dafür, dass es nicht im Puffer der Anwendung landete und die App dann abstürzte, bevor sie es verarbeiten konnte. Verwenden Sie eine Bestätigung, das ist es, was alles andere tut (z. B. SMTP).

Benutzeravatar von ezpz
ezpz

Die Anwendungsschicht hat keine Kontrolle über die Benachrichtigungen auf niedrigeren Schichten (z. B. der Transportschicht), es sei denn, sie werden ausdrücklich bereitgestellt – dies ist beabsichtigt. Wenn Sie wissen möchten, was TCP auf Paketebene tut, müssen Sie herausfinden, auf welcher Ebene TCP arbeitet. Dies bedeutet, dass TCP-Header und ACK-Daten verarbeitet werden.

Jedes Protokoll, das Sie letztendlich zum Übertragen Ihrer Nutzlast verwenden, kann jedoch verwendet werden, um Nachrichten über diese Nutzlast hin und her zu übertragen. Wenn es Ihnen also unangenehm ist, die Bits eines TCP-Headers zu diesem Zweck zu verwenden, richten Sie es einfach in Ihrer Anwendung ein. Zum Beispiel:

A: Send 450 Bytes
B: Recv 450 Bytes
B: Send 'B received 450 Bytes'
A: Recv 'B received 450 Bytes'
A: Continue

Teddys Benutzeravatar
Teddy

Das hört sich an SCTP könnte etwas zum Anschauen sein; Ich denke, es sollte das unterstützen, was Sie wollen. Die Alternative scheint darin zu bestehen, auf UDP umzusteigen und ggf. das Protokoll zu wechseln Trotzdem

1453130cookie-checkFinden Sie heraus, ob eine Nachricht über TCP zugestellt wurde

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy