Der Linux-Netcat-Listener (nc -l) hing

644
Thomas Grusz

Auf meinem Raspberry Pi 3-Terminal (Linux) habe ich Folgendes eingegeben und getroffen Enter:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/' | nc -l 2345 

Der Raspberry Pi 3 ist Teil meines Heimnetzwerks mit einer festen Adresse von 192.168.0.8. Dann habe ich auf meinem Mac Folgendes in meinen Browser (Chrome) eingegeben und drückte Enter:

192.168.0.8:2345 

Ich kann die GET-Anforderung des Browsers auf meinem Linux-Terminal (Raspberry Pi) sehen, aber der ncListener bleibt hängen und sendet die Antwort (die HTTP 302-Weiterleitungsnachricht) nicht an den Browser.

Nur wenn ich das ncProgramm durch Drücken von Ctrl+ stoppe C, erhält der Browser die Antwortnachricht und zeigt die https://www.eff.orgWebsite an.

Hat jemand eine Idee, warum der ncHörer stecken bleibt, anstatt die Antwort zu senden und die Verbindung zu schließen?

0
(1) Woher wissen Sie, dass der "nc" -Prozess "festgefahren" ist? Haben Sie eine Strace gemacht oder das Netzwerk geschnüffelt? (2) Versuchen Sie jedoch zunächst, am Ende der `printf`-Zeichenfolge ein weiteres` \ r \ n` hinzuzufügen. G-Man vor 6 Jahren 0

1 Antwort auf die Frage

0
Kamil Maciorowski

Ich habe dein Problem repliziert. Wenn ich eine Verbindung zu einem anderen ncBrowser herstelle, sehe ich, dass die Antwort sofort gesendet wird. Ich glaube, Ihr Browser erhält auch die Antwort, aber da ncdie Verbindung nicht abgebrochen wird, weiß der Browser nicht, dass dies alles ist, und es ist in Ordnung, mit der Umleitung fortzufahren.

(Hinweis: Während meiner Tests benötigte ich das letzte \r\nin der Antwort von nc, um meinen Browser erfolgreich umzuleiten. Daher verwenden alle meine Beispiele diesen Fix.)


Edit: einfaches Update

Hier habe ich folgendes gefunden:

HTTP-Anforderungen und HTTP-Antworten verwenden ein generisches Nachrichtenformat von RFC 822 zum Übertragen der erforderlichen Daten. Dieses generische Nachrichtenformat besteht aus den folgenden vier Elementen.

  • [...]
  • [...]
  • Eine leere Zeile (dh eine Zeile, bei der der CRLF nichts vorausgeht), die das Ende der Kopfzeilenfelder angibt
  • [...]

Ihre Antwort sollte also lauten:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n\r\n' | ... 

Nachdem Sie dies erhalten haben, sollte Ihr Browser die Umleitung fortsetzen und die Verbindung in ncseinem eigenen Namen beenden . Anfang Dezember 2017 arbeitet es mit Opera und Vivaldi zusammen; Es funktioniert nicht mit Firefox, Chrome oder Safari, für die Sie möglicherweise ein anderes Update benötigen (siehe unten).



Ursprüngliche, jetzt minderwertige Antwort (kann bei Nicht-HTTP-Kommunikation immer noch nützlich sein nc)

Nach dieser Antwort auf Server Fehler Sie verwenden müssen -c, -qoder ähnliche Option, je nach ncAusführung.

In meinem Debian habe ich die -qfähige Version installiert. Dann

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -q 0 -l -p 2345 

funktioniert gut (Hinweis, ich muss auch -pPort angeben). Die Erklärung lautet:

-q seconds
nach EOFauf stdin, warten die angegebene Anzahl von Sekunden und dann beenden. Wenn Sekunden negativ ist, warten Sie immer (Standard).


Wenn Sie nckeine geeignete Option haben, können Sie die Kommunikation von einem Client erkennen und die gesamte Befehlszeile beenden. Ein Beispiel, das in meinem Debian funktioniert bash:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -l -p 2345 | { read foo; sleep 1; kill 0; } 

Ordnet beim Ausführen einer Pipe bashjeden Prozess in einer einzelnen Prozessgruppe an. kill 0sendet Signale an die gesamte Prozessgruppe. Dieser Weg ncwird etwa 1 Sekunde nach Eingang einer Anforderung, die ausgelöst wird, abgebrochen read.

Vielen Dank! Ich habe die einfache Lösung ausprobiert, indem Sie \ r \ n \ r \ n am Ende des Strings hinzugefügt haben, wie Sie es vorgeschlagen haben. Dies funktioniert nur mit dem Opera-Browser (neueste Version). Bei Firefox, Chrome oder Safari (alle neuesten Versionen) bleibt der Prozess jedoch stecken. Wenn ich jedoch die Option "-q 0" zum Befehl "nc" hinzufüge, funktioniert es in allen Browsern. Thomas Grusz vor 6 Jahren 0
@ThomasGrusz Danke. Ich habe mit Vivaldi getestet und meiner Antwort einen Hinweis zur Browser-Kompatibilität hinzugefügt - für zukünftige Benutzer. Kamil Maciorowski vor 6 Jahren 0