2017-04-13 3 views
2

Es ist mein Verständnis, dass ein Schreiben in einen TCP/IP-Socket unteilbar sein wird, wenn die Menge der geschriebenen Daten klein ist. Mit Atom bedeutet das, dass der Empfänger alle Daten oder keine der Daten empfangen wird. Es ist jedoch nicht atomar, wenn die Menge der geschriebenen Daten groß ist. Hab ich recht? und wenn ja, was zählt als groß?Sind TCP/IP Sockets Atomic?

Danke, Bob

+1

Bob, Ihre Frage ist gut und viele Programmierer haben den Fehler, dass sie denken, dass, wenn sie N Bytes in einem TCP-Socket senden, der andere Knoten alle N Bytes lesen wird. Dann laufen sie Funktionstest und funktioniert. Dies ist jedoch ein Fehler, der zu einem bestimmten Zeitpunkt einen Fehler im System auslösen wird. Sie möchten ein einfaches Protokoll für die Anwendungsschicht erstellen, normalerweise TLV (Type, Length, Value). Ich erkläre es hier (das Problem gilt für jede Programmiersprache): http://stackoverflow.com/questions/19839172/how-to-read-all-of-inputstream-in-server-socket-java/19863726#19863726 – rodolk

Antwort

1

Für UDP, das ist wahr, weil alle von der App geschriebenen Daten werden in einem UDP-Datagramm gesendet.

Für TCP ist das nicht wahr, es sei denn, die Anwendung sendet nur 1 Byte Daten gleichzeitig. Ein Schreiben in einen TCP-Socket schreibt alle Daten in einen Puffer, der diesem Socket zugeordnet ist. TCP liest dann Daten aus diesem Puffer im Hintergrund und sendet sie an den Empfänger. Wie viele Daten TCP sendet tatsächlich in einem TCP-Segment auf Variablen seiner Flußsteuerungsmechanismen abhängt, und anderen Faktoren, einschließlich:

  • Fenster von dem anderen Knoten (Empfänger) veröffentlichten Erhalten
  • Datenmenge in früheren gesendet Segmente im Flug, die noch
  • Langsamer Start und die Vermeidung von Staus Algorithmus Zustand
  • vereinbarte maximale Segmentgröße (MSS)

in TCP, können Sie nie assum nicht anerkannt werden e Was die Anwendung in einen Socket schreibt, wird tatsächlich in einem vom Empfänger gelesenen Zustand empfangen. Daten im Socket-Puffer können in einem oder mehreren TCP-Segmenten an den Empfänger gesendet werden. In jedem Moment, in dem Daten verfügbar gemacht werden, kann der Empfänger ein Socket lesen und mit den Daten zurückkehren, die zu diesem Zeitpunkt tatsächlich verfügbar sind.

Natürlich werden alle gesendeten Daten schließlich den Empfänger erreichen, wenn es keinen Fehler in der Mitte gibt, der das verhindert, und wenn der Empfänger die Verbindung nicht schließt oder das Lesen stoppt, bevor die Daten ankommen.

+1

"* es sei denn, die Anwendung sendet nur 1 Byte Daten gleichzeitig *" - auch das ist keine Garantie, da die Daten standardmäßig gepuffert sind. Sie können mehrere 1-Byte-Schreibvorgänge ausführen und sie dennoch zusammen in einem einzelnen TCP-Segment ausgeben lassen, sofern Sie nicht die Socket-Option 'TCP_NODELAY' aktivieren. –

+1

Und in jedem Fall könnten Sie sie alle in einem einzigen Empfangsvorgang erhalten. @RemyLebeau – EJP

+0

@EJP: Ja, wenn mehrere TCP-Segmente im Socket empfangen und gepuffert werden, bevor die App eine neue Leseoperation ausführt. –

2

Nein. TCP ist ein Byte-Stream-Protokoll. Keine Nachrichten, kein Datagramm-ähnliches Verhalten.

+0

Wenn der Server eine 4-Byte-Ganzzahl schreibt und der Client eine 4-Byte-Ganzzahl liest, gibt der Lesevorgang basierend auf den erhaltenen Antworten möglicherweise nur zwei Bytes zurück, da der Schreibvorgang nicht atomar ist und ein nachfolgender Lesevorgang die anderen zwei Bytes zurückgibt . Habe ich das richtig? Bob. – Bob

+0

@Bob, das ist richtig. – rodolk