所以我可以使用这个 netcat 命令来检查 UDP 端口是否打开:
$ nc -vz -u 10.1.0.100 53
Connection to 10.1.0.100 53 port [udp/domain] succeeded!
Run Code Online (Sandbox Code Playgroud)
与 TCP 不同,UDP 是无连接的(即发即忘)。那么在高层次上有没有人知道 netcat 是如何知道 UDP 端口是打开的?它是否要求回复或类似的东西?
archlinux wiki 上有一个 iptables 规则的例子:
# Generated by iptables-save v1.4.18 on Sun Mar 17 14:21:12 2013
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT …Run Code Online (Sandbox Code Playgroud) 如何为我的自定义应用程序保留端口列表?
具体来说,我正在创建的产品有很多流程,并且它们之间有很多交互。
我遇到的问题是——每隔一段时间——操作系统就会窃取我的端口。这是罕见的,但它发生了。
这可能是因为不同的应用程序使用了未指定端口的“::bind”。
有时,当我使用未绑定的套接字调用“::connect”时,我自己的应用程序会窃取端口。从手册页中可以看出:
如果套接字尚未绑定到本地地址,connect() 会将其绑定到一个地址,除非套接字的地址族是 AF_UNIX,否则该地址是未使用的本地地址。
所以我的问题是,我可以保留我需要的端口以便操作系统不使用它们吗?这可以通过 /etc/services 完成吗?或者有不同的方法吗?
我最近在这里了解了/dev/udp和/dev/tcp伪设备。它们是特定于某些 GNU/Linux 发行版还是我可以在其他 unix 系统上找到它们?
它们是否以某种方式标准化?
到目前为止,我已经能够在 OS X、Arch Linux 和 CentOS 上成功地使用它们。
我没有对我的硬件或内核配置(所有默认设置、全新操作系统安装、Linux 内核 3.11 TCP/IP 堆栈)进行任何异常处理,我通过 TCP 平均每秒发送大约 383 万条消息,而我平均只有 0.75每秒通过 UDP 发送百万条消息。这似乎完全违背了我对这两个协议的期望。
造成巨大差异的最可能原因是什么,我如何在 Ubuntu 13.10 上对其进行诊断?
#TCP RESULTS
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 65536 64 10.00 1963.43 32.96 17.09 5.500 2.852
#UDP RESULTS
Socket Message Elapsed Messages CPU Service
Size Size Time Okay Errors Throughput Util Demand
bytes bytes secs …Run Code Online (Sandbox Code Playgroud) 当我执行以下 Netcat 命令并使用Wireshark查看数据包时,它说 UDP 数据包格式错误。
$ echo "this is a test" | nc -u 127.0.0.1 53
Run Code Online (Sandbox Code Playgroud)
同样,$ echo "this is a test" > /dev/udp/127.0.0.1/53在 Wireshark 中使用诸如产生“格式错误的数据包”错误之类的命令。
echo 命令被发送/传递到 Netcat 服务器,没有错误。但这让我想知道:是否可以使用 echo 或其他一些本机 Unix 工具手动构建正确的 UDP 数据包?
我正在使用 Debian 和 macOS。
树莓派上的组播 UDP
我还没有把事情缩小到足够的范围来知道我的问题是因为 debian、raspbian,还是因为我完全遗漏了某些东西。
我有一个 python 应用程序,它使用多播 UDP 让网络上的其他设备知道我的应用程序已启动并在特定 IP 地址上可用。
UDP 多播组是 239.255.250.250,端口是 9131。如果我运行 tcpdump,我可以看到我尝试发送的数据包实际上正在发送数据,但我从未在网络上的其他机器上看到任何通过。
还有其他设备使用具有相同多播组和端口的相同类型的“信标”,我可以看到这些数据包通过其他机器。路由器没有防火墙,在这一点上我真的没有选择。
以下是我知道如何运行的基本诊断。糟糕的 udp chksum 看起来可能没有帮助,但我对此一无所知。
ifconfig 的输出
eth0 Link encap:Ethernet HWaddr b8:27:eb:b2:79:12
inet addr:192.168.2.7 Bcast:192.168.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1682 errors:0 dropped:0 overruns:0 frame:0
TX packets:1686 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:119105 (116.3 KiB) TX bytes:169570 (165.5 KiB)
Run Code Online (Sandbox Code Playgroud)
应用程序运行时 tcpdump 的输出
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
03:29:15.722653 IP (tos 0x0, ttl 1, …Run Code Online (Sandbox Code Playgroud) 我想要一个程序P,它从 读取stdin和写入stdout,但将它连接到nc或任何其他端口,以便它从某个端口读取并输出到另一个端口。
# The reading is easy, here P reads from port 50505
nc -l 50505 | P
Run Code Online (Sandbox Code Playgroud)
我如何让它写回端口 60606?
如果我执行ss -lu以查看所有侦听的 UDP 套接字,则不会显示任何套接字。如果我执行ss -au,它列出了所有(侦听和非侦听)UDP 套接字,则“侦听”套接字显示为 UNCONN(见下文)。
这背后的逻辑是什么?例如,运行atftpd监听连接,状态应该是 LISTEN 而不是 UNCONN,不是吗?
T60:~ # lsof -n | sed -n '1p;/UDP/p'
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae 963 avahi 11u IPv4 9088 0t0 UDP *:mdns
avahi-dae 963 avahi 12u IPv4 9089 0t0 UDP *:44639
cupsd 1238 root 10u IPv4 8160 0t0 UDP *:ipp
dhcpcd 2072 root 7u IPv4 532052 0t0 UDP *:bootpc
dhclient6 13131 root 5u IPv6 38031 0t0 UDP *:dhcpv6-client …Run Code Online (Sandbox Code Playgroud) 谁能解释以下输出netstat -plunt?
udp 0 0 0.0.0.0:58262 0.0.0.0:* 1163/avahi-daemon:
udp 0 0 0.0.0.0:17500 0.0.0.0:* 3779/dropbox:u
udp 0 0 0.0.0.0:5353 0.0.0.0:* 1163/avahi-daemon:
Run Code Online (Sandbox Code Playgroud)
0.0.0.0:* 是什么意思?是所有端口都被监听还是其他什么?