36

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の動作ですか?

4

4 に答える 4

45

がUDPソケットをリッスンしているときnc、それは受信した最初のパケットの送信元ポートと送信元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の場合、connectrejectは、のIPおよびポートと一致しないすべてのパケットを拒否しますconnect

于 2011-10-08T12:56:47.883 に答える
4

-k次のオプションを使用します。

nc -l -u -k 0.0.0.0 10000
  • -kはキープアライブを意味し、netcatは各接続後にリッスンし続けます
  • -uはUDPを意味します
  • -lポート10000でリッスン
于 2015-03-01T11:42:37.563 に答える
3

私の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
于 2016-12-16T16:06:18.077 に答える
1

受け入れられた答えが説明するように、UDPプロトコルでncatサポートしていないようです。--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"
于 2018-12-04T22:31:24.160 に答える