netcat(nc)でUDP通信する使い方まとめ(-u オプションとBSD/GNU/RHEL系統別)

nc(netcat)でUDP通信するには -u オプションを付けるだけです。ただし nc には実装がいくつかあり、特に待ち受け(-l)のオプションの書き方が系統によって違います。ここを取り違えるとコマンドがエラーになったり、意図と違う動きをします。この記事では基本の使い方と、系統ごとの違いを実際に動かして確認した結果でまとめます。

基本:ncでUDPを送受信する

以降の基本操作は、macOS標準のnc(BSD系、OpenBSD nc由来)で実機確認したコマンドです。-u での基本的な送受信はどの系統でも同じですが、待ち受け(-l)まわりのオプションは系統ごとに変わります。詳しくは次の章にまとめました。

受信側(listen)

nc -u -l 1234

指定したポートでUDPパケットの到着を待ちます。TCPと違って「接続」という概念がないので、パケットが届いた時点で内容がそのまま表示されます。

送信側

echo "hello" | nc -u 127.0.0.1 1234

宛先ホストとポートにUDPパケットを送ります。標準入力から読んだ内容がそのままパケットの中身になります。

双方向のやり取り

nc は標準入出力を使うプログラムなので、受信側・送信側の両方で手入力しながらチャットのようにやり取りできます。手元で動かして確認したところ、受信側は最初のパケットを受け取った時点で送信元のアドレスを覚え、そこへ返信できます。

# 受信側(このまま何か入力すると送信側に届く)
nc -u -l 1234

# 送信側(先にここから何か送ってから)
nc -u 127.0.0.1 1234

先に送信側から何か送っていないと、受信側は誰に返信すればいいか分からず何も送れません。順番に注意してください。

-v(verbose)で状況を確認する

nc -u -v -w1 127.0.0.1 1234
Connection to 127.0.0.1 port 1234 [udp/*] succeeded!

このメッセージは「送信できた」ことを示すだけで、相手が実際に受け取ったことは保証しません。UDPはコネクションレスなので、ローカルでソケットの向き先を設定できた時点で “succeeded” と表示されます。ポートが閉じていても同じメッセージが出ることがあるので過信は禁物です(詳しくは後述の -z の項目を参照)。

-w(タイムアウト)の注意点

-w秒数 は接続や標準入力が指定秒数アイドルだと切断するオプションですが、待ち受け(-l)側には効きません。nc -u -l -w1 1234 としても、受け側は永久に待ち続けます。-w1 を付けた受信側を起動して2.5秒待っても終了しないことを手元で確認しました。タイムアウトさせたいのは基本的に送信側だけです。

nc には3つの系統がある

nc という名前のコマンドは1つではありません。よく使われるのは次の3系統で、待ち受けオプションの書き方が違います。

系統主な入手経路UDP待ち受けの書き方-p の意味
OpenBSD ncmacOS標準・netcat-openbsd(Debian/Ubuntu)nc -u -l 1234送信元ポートの指定(クライアント用)
GNU netcat(traditional)netcat-traditional(Debian)nc -u -l -p 1234待ち受け・送信元ともにローカルポートの指定
Nmap Ncatnmap-ncat(RHEL系)・macOSは brew install nmap・Windowsは公式サイトのインストーラまたは単体の ncat.exencat -u -l 1234送信元ポートの指定(-l と併用可)

同じ -p でも系統によって「待ち受けポートの指定に使えるか」が変わるのが最大の落とし穴です。1つずつ実機・公式マニュアルで確認した内容を書きます。Windowsには標準の nc は存在しませんが、上表のNcatが公式に対応しています。オプションの体系はmacOS/Linuxと共通なので、この章の内容がそのまま使えます(導入と実際の使い方はインストールの章で紹介する別記事へ)。

OpenBSD nc(macOS標準)

macOS標準の nc(Appleがカスタムした版)では、待ち受けポートは位置引数で指定します。-l-p を同時に使うとエラーになります。

$ nc -u -l -p 1234
nc: missing port with option -l

手元のmacOSで試すとこのエラーになりました。nc -u -l 1234 のように位置引数でポートを指定してください。

補足:純正のOpenBSD版nc(Debianの netcat-openbsd パッケージなど)の公式マニュアルでは、-l の待ち受けポートは位置引数でも -p オプションでもどちらでも指定できると説明されています。macOSのnc(Apple版)はこの点でOpenBSD本家より制限が厳しく、-p-l の併用を許可していません。同じ「OpenBSD nc」でも配布元によって細部が異なるので、位置引数で書く癖をつけておくのが無難です。

GNU netcat(traditional)

こちらは逆に -p での指定が基本形です。公式マニュアルのSYNOPSISには次のように書かれています。

nc -l -p port [-options] [hostname] [port]

UDPで待ち受けるなら次のようになります。

nc -u -l -p 1234

-l 1234 のように位置引数だけで待ち受けポートを指定する古い記事もありますが、GNU netcat(traditional)の公式な書き方は -p を使う形です。手元の環境にGNU netcat(traditional)が無いため実機での動作確認はできていません。上記はDebianの公式マニュアルページで確認した内容です。

Nmap Ncat

Ncatは -p(--source-port)を -l と組み合わせても動きます。試したところ、ncat -u -l -p 1234 は正常に待ち受けを開始し、パケットも受信できました。位置引数での指定(ncat -u -l 1234)も同様に使えるので、どちらの書き方でも困りません。

ncat -u -l 1234
# または
ncat -u -l -p 1234

自分の nc がどの系統か見分ける

まず ncat --version のように系統名入りでバージョンを表示してくれるコマンドならそれで一発です。Ncatはこれで分かります。

nc(netcat)そのものにはバージョン表示オプションが無い実装が多いので、次の方法で見分けます。

Debian/Ubuntu系なら、readlink -f $(command -v nc)nc の実体のパスを確認し、そのパスを dpkg -S に渡せばどのパッケージが提供しているか分かります。netcat-openbsdnetcat-traditional のどちらかが出るはずです。RHEL/Fedora系なら rpm -q nmap-ncat で入っているか確認できます。macOSの /usr/bin/nc は常にApple版のOpenBSD nc系で、別に ncat コマンドがあれば brew install nmap で入れたNcatです。

どうしても分からないときは、本記事で確認した nc -u -l -p ポート番号 を試す方法もあります。エラーになれば macOS標準のnc系統、そのまま起動すればGNU netcat(traditional)かNcatです。

-z でポートスキャンする(が、UDPでは過信禁物)

-z はデータを送らずに接続だけ試す「ゼロI/Oモード」です。TCPのポートスキャンでは定番ですが、UDPでは系統によって挙動が大きく違うことを実機で確認しました。

macOS標準のnc(BSD系)で、誰も待ち受けていないポート宛てに -z を実行すると次のようになりました。

$ nc -u -z -v -w1 127.0.0.1 40000
Connection to 127.0.0.1 port 40000 [udp/*] succeeded!

実際に何かが待ち受けているポートに対しても結果は同じ(succeeded、終了コード0)で、開いているか閉じているかを区別できません。UDPパケットを送りっぱなしにして応答を待たないだけなので、そもそも判定の材料になっていないのです。

一方Ncatは、ICMPの port unreachable を待って判定するぶん、ローカルループバックでは開いているポートと閉じているポートで結果が変わりました。

# 誰も待ち受けていないポート
$ ncat -u -z -v -w1 127.0.0.1 40000
Ncat: Connection refused.

# 待ち受け中のポート
$ ncat -u -z -v -w1 127.0.0.1 40001
Ncat: UDP packet sent successfully

ただしこれはICMPの port unreachable がそのまま届くローカル環境だからこそ判定できています。実際のネットワーク越しではファイアウォールがICMPを止めていることが多く、Ncatでも「応答が無い=閉じている」と断定はできません。UDPの疎通確認をきちんと行いたい場合は、-z の結果だけに頼らず次の記事も参照してください。

UDPポートが開いているか確認する方法

インストール(2026年時点)

# macOS: ncは標準搭載。ncat(Nmap Ncat)を使いたい場合
brew install nmap

# Debian/Ubuntu: 既定のnc(OpenBSD系)
sudo apt install netcat-openbsd

# Debian/Ubuntu: GNU netcat(traditional)がどうしても必要な場合
sudo apt install netcat-traditional

# RHEL/CentOS/Rocky/Alma/Fedora系: Ncat
sudo dnf install nmap-ncat   # 古い環境は yum install nmap-ncat

Windowsでの手順は別記事にまとめています。

WindowsでUDP通信・ポート確認をする方法

別のツール:socat

nc よりさらに柔軟にソケットを扱いたい場合は socat という選択肢もあります。UDP↔TCP変換やSSL終端など、ncではできないことも多くこなせますが、その分オプションが複雑です。用途がシンプルな送受信・疎通確認であれば、まずはnc(またはncat)で十分です。socatの詳しい使い方は本記事では扱いません。

さいごに

  • UDP通信そのものは -u を付けるだけで難しくありません。ハマりどころは系統ごとの -l/-p の書き方の違いです。
  • macOS標準のncは -l-p を併用できないので位置引数で書く、GNU netcat(traditional)は -p での指定が基本、Ncatはどちらでも動く、と覚えておけば迷いません。
  • ポートが開いているかの確認は -z だけに頼らず、UDPポートが開いているか確認する方法も参照してください。
  • そもそもの「なぜtelnetではだめでncを使うのか」は コマンドラインでUDP通信を試す方法 にまとめています。
  • Windowsでの導入とPowerShellでの扱いは WindowsでUDP通信・ポート確認をする方法 にまとめています。