NetcatとUDPで動作する奇妙な動作に気づきました。 UDPポートで待機するnetcatのインスタンス(インスタンス1)を開始します。
nc -lu -p 10000
だから私はnetcat(インスタンス2)の別のインスタンスを起動し、私のプロセスにデータグラムを送信しようとします:
nc -u 127.0.0.1 10000
データグラムが表示されます。しかし、インスタンス2を閉じてnetcat(インスタンス3)を再起動すると、次のようになります。
nc -u 127.0.0.1 10000
インスタンス1の端末でデータグラムを表示できません。不思議なことに、オペレーティングシステムはインスタンス2に対してインスタンス3で別のUDPソースポートを割り当てており、問題があります。同じインスタンスの2ソースポート(例50000)を使用している場合:
nc -u -p 50000 127.0.0.1 10000
再びnetcatのインスタンス1がデータグラムを受信します。 UDPはコネクションレスプロトコルなので、なぜですか?これは標準のnetcatの動作ですか?
nc
がUDPソケットをリッスンしているときは、受信する最初のパケットのソースポートとソースIPに「ロックオン」します。このトレースをチェックしてください:
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f\n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
ここでは、UDPソケットを作成し、アドレスを再利用できるように設定し、ポート10,000にバインドしていることがわかります。最初のデータグラムを(ポート52,832から)受信するとすぐに、connect
システムコールを発行して、それを127.0.0.1:52,832に「接続」します。 UDPの場合、connect
は、connect
のIPとポートに一致しないすべてのパケットを拒否します。
使用 - -k
オプション:
nc -l -u -k 0.0.0.0 10000
私のOSバージョンでnetcatをあきらめた場合、これはかなり短く、仕事が完了します。
#!/usr/bin/Ruby
# Receive UDP packets bound for a port and output them
require 'socket'
require 'yaml'
unless ARGV.count == 2
puts "Usage: #{$0} listen_ip port_number"
exit(1)
end
listen_ip = ARGV[0]
port = ARGV[1].to_i
u1 = UDPSocket.new
u1.bind(listen_ip, port)
while true
mesg, addr = u1.recvfrom(100000)
puts mesg
end
受け入れられた回答が説明するように、ncat
はUDPプロトコルで--keep-open
をサポートしていないようです。ただし、表示されるエラーメッセージは回避策のヒントです。
Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING.
--exec /bin/cat
を追加するだけで、--keep-open
を使用できます。入力と出力の両方が/bin/cat
に接続されます。クライアントが送信するものはすべてコピーされて「エコーサーバー」に変換されます。
入力でより便利なことを行うには、シェルのリダイレクト演算子を使用できます(したがって、--sh-exec
ではなく--exec
が必要です)。端末でデータを表示するために、これは機能します:
ncat -k -l -u -p 12345 --sh-exec "cat > /proc/$$/fd/1"
注意:上記の例では、ncatの親シェルのstdoutにデータを送信します。追加のリダイレクトと組み合わせると混乱を招く可能性があります。すべての出力をファイルに単純に追加する方が簡単です。
ncat -k -l -u -p 12345 --sh-exec "cat >> ncat.out"