tl; dr
Siehe Schlussfolgerungen ganz am Ende.
Präambel
Ich kann deine Ergebnisse erklären. Ich benutze Kubuntu, nicht Debian, dennoch glaube ich, dass die Hauptpunkte allgemein sind. Um zu verstehen, was passiert, ist es gut, den TCP-Fall zu analysieren und dann mit UDP zu vergleichen.
Wenn Sie meine Forschung replizieren möchten, beenden Sie den Vorgang nicht, oder töten Sie ihn nc
nicht, es sei denn, ich sage das oder es endet von selbst. Töte nc
s, wenn ich sage. Es ist sehr wichtig. Nachdem Sie die vollständige Antwort gelesen haben, werden Sie den Punkt verstehen.
Diese Analyse erfordert mehrere Terminals (oder tmux
, oder screen
).
TCP-Fall
Beseitigen Sie zunächst alle bisherigen nc
Prozesse.
killall nc
Einen Abhörprozess ausführen:
nc -l 6900
Untersuchen Sie die Ausgabe von lsof -i :6900
. Ihr nc
wird dort als Abhörvorgang aufgeführt.
Führen Sie einen Verbindungsprozess aus:
nc localhost 6900
Untersuchen Sie die Ausgabe von lsof -i :6900
. Die beiden nc
s sind die Enden der aufgebauten Verbindung.
Da Ihr erster nc
nicht mehr hört, können Sie einen zweiten Hörprozess ausführen :
nc -l 6900
und ein zweiter Verbindungsprozess:
nc localhost 6900
Geben Sie etwas in jede Konsole ein, auf der es nc
läuft (vergessen Sie nicht, Enterjedes Mal einen Treffer zu treffen ). Sie werden feststellen, dass es zwei getrennte Verbindungen gibt. Sie können eine dritte einrichten, wenn Sie möchten.
Überprüfen Sie noch lsof -i :6900
einmal. Obwohl die beiden (früher) zuhörenden nc
s denselben Port verwenden 6900
, mischen sich die beiden Verbindungen nicht, da nc
s an den anderen Enden unterschiedliche Ports verwenden. Wenn ein Paket an den 6900
Port kommt, überprüft der Kernel diesen anderen Port und entscheidet, welche der (früher) hörenden nc
s es empfangen sollen.
Sie können zusätzliche (ungepaarte) Verbindungen herstellen nc
:
nc localhost 6900 || echo fail
und es wird sofort scheitern.
Sie haben noch zwei getrennte Verbindungen. Beenden Sie eines nc
von jedem Paar mit Ctrl+ Coder Ctrl+ Dund Sie werden feststellen, dass die entsprechenden Enden ebenfalls enden. Dies liegt daran, dass TCP verbindungsorientiert ist. Wenn eine Verbindung von einem ihrer Enden aus ordnungsgemäß beendet wird, wird das andere Ende benachrichtigt, damit es entsprechend reagieren kann - in diesem Fall wird es nc
einfach beendet.
UDP-Fall
Wichtig:
killall nc
Führen Sie die folgenden Befehle nacheinander aus, und zwar jeweils in einer separaten Konsole. Überprüfen Sie auch lsof -i :6900
nach jedem, was passiert. Die Befehle sind:
nc -ul 6900 nc -u localhost 6900
Geben Sie etwas in das erste ein ("Hören") nc
(Treffer Enter); überprüfen lsof -i :6900
; tippe etwas in den zweiten nc
(hit Enter); überprüfen Sie noch lsof -i :6900
einmal und beachten Sie die Änderung.
Bereiten Sie dann ein anderes Paar vor (in separaten Konsolen):
nc -ul 6900 nc -u localhost 6900
Führen Sie einige Zeichenketten hin und her, um zu sehen, ob es funktioniert. Beenden Sie einen nc
mit Ctrl+ C( Ctrl+ Dfunktioniert nicht) und beachten Sie, dass der andere nc
(am entsprechenden Ende) noch läuft. Die andere Seite der "Verbindung" weiß nicht, wann die "Verbindung" "beendet" ist. Wie Sie sehen konnten lsof
, weiß es nicht, dass die "Verbindung" "hergestellt" ist, bis die Daten zu fließen beginnen.
Ich zitiere hier einige Worte, weil UDP verbindungslos ist und das der Hauptunterschied ist.
Was kann kompliziert werden?
Bisher sollte alles geklappt haben. Es ist an der Zeit, Ihre vorherigen Ergebnisse zu erklären, wenn die Dinge nicht funktionierten.
Wichtig:
killall nc
Bereiten Sie ein "Hören" vor nc
:
nc -ul 6900
Überprüfen lsof -i :6900
. Die Ausgabe wird wie folgt aussehen:
… UDP *:6900
Bereiten Sie eine "Verbindung" vor nc
:
nc -u localhost 6900
Überprüfen lsof -i :6900
. Beispielausgabe (Sie 54766
können variieren):
… UDP *:6900 … UDP localhost:54766->localhost:6900
Übergeben Sie einige Daten von der zweiten nc
zur ersten. Überprüfen lsof -i :6900
:
… UDP localhost:6900->localhost:54766 … UDP localhost:54766->localhost:6900
Beenden Sie die Sekunde nc
mit Ctrl+ C. Wieder lsof -i :6900
:
… UDP localhost:6900->localhost:54766
Dies bedeutet, dass die ersten nc
"Gespräche" nur mit dem Port 54766
am anderen Ende der "Verbindung" erfolgen. Wenn Sie versuchen, sich mit einem Dritten zu verbinden nc
:
nc -u localhost 6900
Es würde höchstwahrscheinlich einen anderen zufälligen Port auf seiner Seite wählen. Versuch es. Sie können (ungefähr) zwei Zeilen "übergeben", genau wie Sie es in Ihrer Frage getan haben, bevor diese nc
beendet wird.
(Hinweis: Dieser nc
Vorgang wird aufgrund eines ICMP-Pakets abgebrochen, siehe hierzu ; Sie können das Paket so aufnehmen wireshark
wie ich.)
Sie können jedoch den richtigen Port erzwingen (ändern 54766
, um sich an Ihre lsof
Ausgabe anzupassen):
nc -up 54766 localhost 6900
und dieser vierte nc
wird in der Lage sein, Daten zu übergeben! Der erste nc
wird den Unterschied nicht sehen. Es wird so sein, als ob der zweite nc
nie beendet wurde.
Beenden Sie die vierte, nc
bevor Sie fortfahren. Lass den ersten laufen.
Die -v
Option
Das letzte Rätsel ist: Warum wurde es nc -v -u localhost 6900
sofort beendet?
Im obigen Beispiel hatten wir vier nc
s:
- der erste - "Zuhören";
- der zweite - erfolgreich verbunden, dann beendet;
- der dritte - kann aufgrund eines falschen lokalen Ports keine Verbindung herstellen;
- der vierte - kann dank rechtem (erzwungenem) lokalem Port eine Verbindung herstellen.
In meinem Kubuntu überträgt nc -uv …
, wenn es der zweite ist, nur wenige X
Zeichen, wahrscheinlich um die Verbindung zu prüfen. Wenn es sich um die dritte handelt, müssen nicht (ungefähr) zwei Zeilen externer Eingänge ausfallen, sondern sofort. Wenn die erste nc
noch läuft, versuchen Sie Folgendes:
nc -uv localhost 6900
Es sollte scheitern Sie können auch hier den richtigen Port erzwingen, und er funktioniert genauso wie der vierte nc
im obigen Beispiel.
nc -uvp 54766 localhost 6900
Wenn ich das anrufe, sehe ich X
-s in der Konsole der ersten nc
.
Reinigung
killall nc
Schlussfolgerungen
Mir scheint, Sie hatten (das "Hören"), nc
das bereits mit einem bestimmten Port auf der anderen Seite der "Verbindung" verbunden war, ganz sicher, weil ein anderer nc
(oder etwas anderes) mindestens ein Paket erfolgreich übertragen hatte. Ihre anderen nc
s haben versucht, andere Ports auf ihrer Seite zu verwenden und konnten nicht mit diesem ersten kommunizieren.
Wenn ich ersetzen
localhost
mit127.0.0.1
, gibt es Fortschritte
Irrelevant. Ich denke, in diesem Fall haben Sie gerade mit dem Saubermachen begonnen, wie wir es später getan haben killall nc
.