Osx

nc 不等待 OS X 上的伺服器斷開連接

  • October 15, 2014

如何使ncOS X Mavericks 上的客戶端保持套接字打開並讀取數據,直到伺服器斷開套接字?

我想通過將數據發送到伺服器nc然後使用響應。問題是nc數據發送後斷開套接字,而不等待伺服器的響應。

這只會寫入數據然後退出:

$ echo "my instruction here" | nc 127.0.0.1 $MY_PORT

這將寫入數據,然後即使伺服器已斷開連接也不會退出:

$ cat <(echo "my instruction here") - | nc 127.0.0.1 $MY_PORT

OS X Mavericks 上的nc手冊頁有以下範例,用於發送HTTP GET請求和列印響應,但它不起作用。它只是發送請求然後退出而不等待伺服器的響應。似乎手冊頁的資訊不正確?

$ echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80

nc 的預設行為是在標準輸入關閉時關閉連接。要進行更改,您可以在 Linux 上使用 -q 選項(如-q -1),在 OS X 上可能相同。有關詳細資訊,請參閱手冊頁。

編輯:看起來 OS X nc 不支持 -q 開關或類似的東西。在這種情況下,您需要通過執行以下操作確保 stdin 不會關閉:

(迴聲“foo”;睡眠 100000)| 數控…

一旦監聽nc(伺服器)關閉,客戶端nc也會退出。

在 Mac OS X 上,您可以open -a 'Activity Monitor'驗證這一點。

範例掛起的原因nc & cat不是nc,而是cat繼續保持其標準輸入和標準輸出打開以供讀寫。

但是,當在偵聽關閉cat後嘗試寫入管道時,會引發並終止。nc``SIGPIPE``cat

# cat & SIGPIPE test
(sleep 1; echo hi) | 
  (trap 'echo "received signal $(($? - 128))" 1>&2' EXIT; cat) | :

kill -l 13
man bash | less -p 'EXIT STATUS'
man bash | less -Ip '128\+n'

作為 Niklas Berglund 的解決方法的替代方法,可以擷取客戶端的退出以殺死包括掛起命令nc在內的整個程序組。cat

# console 1
# ctrl-c will "kill 0" entire process group sh -c '...'
nc -l 8080  

# console 2
# script command (FreeBSD version) will implicitly run: man 2 setsid
# kill 0 will therefore only kill the entire process group sh -c '...' 
# run in a script kill 0 would otherwise kill the entire script
# cf. also https://github.com/jerrykuch/ersatz-setsid 
script -q /dev/null sh -c '
(echo "my instruction here"; cat) | (trap "kill 0" EXIT; nc 127.0.0.1 8080)
'

引用自:https://unix.stackexchange.com/questions/150385