菜鸟科技网

nc命令如何实现UDP通信?

nc 是一个功能强大的网络工具,被誉为“网络工具中的瑞士军刀”,它既能作为客户端,也能作为服务器,可以用于 TCP 和 UDP 协议,UDP 是一种无连接、不可靠的协议,与 TCP 的工作方式有很大不同,因此在 nc 中使用 UDP 也有一些特定的注意事项。

nc命令如何实现UDP通信?-图1
(图片来源网络,侵删)

核心概念:UDP vs TCP

在使用 nc 之前,理解 UDP 和 TCP 的区别至关重要:

  • TCP (Transmission Control Protocol):

    • 面向连接: 在传输数据前,必须先通过“三次握手”建立一个连接。
    • 可靠传输: 通过序列号、确认应答、重传机制等确保数据无差错、不丢失、不重复,且按序到达。
    • 有边界: 数据以报文段(Segment)为单位传输,nc 能清晰地看到数据的开始和结束。
    • 速度较慢: 因为需要建立连接和维护状态,所以开销较大。
  • UDP (User Datagram Protocol):

    • 无连接: 发送数据前不需要建立连接,直接将数据包(Datagram)发送出去。
    • 不可靠传输: 不保证数据包的顺序、不保证不丢失、不保证不重复,它只管“尽力而为”地发送。
    • 无边界: 数据流是连续的,nc 无法自动判断一个数据包的结束和下一个的开始。
    • 速度快: 开销小,传输效率高,适用于对实时性要求高但能容忍少量丢包的场景(如视频、语音、DNS 查询等)。

nc 命令的基本 UDP 语法

要使用 nc 进行 UDP 通信,关键在于使用 -u 选项。

nc命令如何实现UDP通信?-图2
(图片来源网络,侵删)
# nc -u [选项] 主机名 端口号
  • -u: 指定使用 UDP 协议。这是最重要的选项。

UDP 服务器(监听和接收数据)

UDP 服务器会绑定到一个指定的端口,并等待接收来自任何客户端的数据。

步骤:

  1. 启动服务器:在终端 A 中运行以下命令。-l 表示监听(listen),-u 表示 UDP。

    # nc -lu -p 端口号
    # 监听本机的 9999 端口
    nc -lu -p 9999
    • -l: 监听模式。
    • -u: UDP 模式。
    • -p: 指定端口号。
  2. 发送数据:在另一个终端 B 中,使用 nc 作为 UDP 客户端向服务器的 IP 和端口发送数据。

    nc命令如何实现UDP通信?-图3
    (图片来源网络,侵删)
    # nc -u 服务器IP地址 端口号
    # 向本机(127.0.0.1)的 9999 端口发送 "Hello, UDP Server!"
    nc -u 127.0.0.1 9999

    现在在终端 B 中输入任何文本并按回车,这些数据就会被发送到终端 A。

  3. 查看接收:回到终端 A,你会看到刚刚发送过来的数据。

    # 终端 A (nc -lu -p 9999)
    Hello, UDP Server!
    This is another message.

重要提示:UDP 服务器在接收到数据后,默认情况下不会自动退出,它会一直运行,等待更多的数据,你可以使用 Ctrl + C 来终止它。


UDP 客户端(发送数据)

在上面的场景二中,我们已经展示了如何作为客户端发送数据,客户端非常简单,就是指定 -u 选项、目标 IP 和端口。

示例:

# 向 192.168.1.100 的 12345 端口发送一条测试消息
echo "This is a test" | nc -u 192.168.1.100 12345

这个命令通过管道 将 echo 命令的输出作为 nc 的输入,然后发送出去。


UDP 端口扫描(探测端口)

虽然 nc 主要用于数据传输,但也可以用来扫描一个 UDP 端口是否开放,UDP 端口扫描比 TCP 扫描要复杂和不可靠,因为 UDP 没有像 TCP 那样的“三次握手”或“RST”包来明确表示端口关闭。

原理:

  • 开放端口:如果端口开放,目标主机会返回一个 ICMP "端口不可达" 的错误消息(在某些系统上可能不返回任何消息)。
  • 关闭/过滤的端口:如果端口关闭,目标主机会返回一个 ICMP "端口不可达" 消息,如果被防火墙过滤,则没有任何响应。

由于响应不明确,UDP 扫描的结果通常是不可靠的。-z 选项可以用来扫描而不发送任何数据。

示例:

# 扫描 192.168.1.100 的 161-163 端口(SNMP 常用端口)
nc -uzv 192.168.1.100 161-163
  • -z: 表示扫描模式,只报告开放的端口,不发送数据或读取数据。
  • -u: UDP 模式。
  • -v: 详细输出,显示扫描过程。

输出可能如下:

nc: connect to 192.168.1.100 port 161 (udp) failed: Connection refused
nc: connect to 192.168.1.100 port 162 (udp) failed: Connection refused
nc: connect to 192.168.1.100 port 163 (udp) failed: Connection refused

注意Connection refused 这个消息在某些系统上可能意味着端口是关闭的,但在另一些系统上也可能意味着被防火墙拦截了,不能完全依赖这个结果来判断端口是否开放。


实际应用案例:模拟 DNS 查询

DNS (Domain Name System) 是使用 UDP 协议的经典应用,我们可以用 nc 手动发送一个 DNS 查询请求。

  1. 获取 DNS 请求的二进制数据 我们需要一个 DNS 查询的原始数据包,通常可以从网络抓包(如使用 tcpdumpWireshark)获取,或者使用 dig 命令生成并抓包,这里我们假设你已经有了一个 dns_query.bin 文件。

  2. 发送查询 使用 nc 将这个二进制文件发送到 DNS 服务器的 53 端口。

    # 假设 DNS 服务器是 8.8.8.8
    # 使用 -w 设置超时时间,因为 UDP 可能没有响应
    nc -u -w 1 8.8.8.8 53 < dns_query.bin
  3. 接收响应 DNS 服务器会返回一个 DNS 响应,你可以将响应重定向到一个文件中,然后用 Wireshark 或其他工具分析。

    nc -lu -p 5353 -w 1 > dns_response.bin

    然后在另一个终端运行发送命令:

    nc -u -w 1 8.8.8.8 53 < dns_query.bin

    响应就会被保存到 dns_response.bin 文件中。


nc 处理 UDP 的关键注意事项

  1. 无连接性:客户端不需要先“连接”到服务器,你可以在任何时候向任何 IP 和端口发送数据,即使那里没有任何人在监听。
  2. 无边界性:这是 nc 处理 UDP 最大的挑战,如果你一次性发送大量数据,nc 在另一端接收时可能会将它们全部读入一行,或者根据缓冲区大小进行分割,它无法知道一个“消息”在哪里结束,对于结构化协议(如 DNS),通常每个数据包是独立的,对于文本消息,可能需要约定分隔符(如换行符 \n)。
  3. 不可靠性:发送的数据包可能会丢失、重复或乱序。nc 本身不会处理这些情况,如果你需要可靠性,必须在上层应用中实现确认和重传机制。
  4. 防火墙:UDP 端口很容易被防火墙过滤,如果你的 nc 服务器无法接收数据,首先要检查防火墙是否阻止了相应端口的 UDP 流量。
  5. 超时:在进行 UDP 通信时,特别是扫描或等待响应时,建议使用 -w 选项设置一个超时时间,否则 nc 可能会无限期地等待下去。
    nc -u -w 5 127.0.0.1 9999
    # 等待 5 秒,如果没有数据连接,则退出
功能 命令 说明
启动 UDP 服务器 nc -lu -p <port> 在指定端口上监听并接收 UDP 数据。
启动 UDP 客户端 nc -u <host> <port> 向指定主机的端口发送 UDP 数据。
带超时的客户端 nc -u -w <seconds> <host> <port> 发送数据后等待指定秒数后超时退出。
UDP 端口扫描 nc -uzv <host> <port> 尝试扫描 UDP 端口,结果不可靠。
发送文件内容 cat <file> \| nc -u <host> <port> 作为数据发送。

nc 是学习和测试 UDP 协议的绝佳工具,因为它简单直接,但在生产环境中,对于需要可靠性、复杂协议或高性能的场景,通常会使用更专业的库或应用程序。

分享:
扫描分享到社交APP
上一篇
下一篇