关于p2p应用中的UDP端口
About UDP port in p2p application
我正在做一个 DHT 的小型演示项目(仅限 p2p 路由,如 Chord、Pastry 等),我对 P2P 网络中的传输细节感到困惑。
假设所有peer都使用UDP进行通信,端口为10050,固定不变,那么考虑两种典型情况:
- A 可能会向 B 发送 "JOIN" 消息。
- 此外,B 可能会根据 p2p 性质向 A 发送 "JOIN" 消息(或其他消息)。
情况一,报文的目的端口必须是10050;
情况2,报文的目的端口必须是10050;
我想知道两种情况下消息的源端口是什么?如果它是由系统调用决定的随机端口,DHT 协议栈需要处理 10050 和随机端口 上的数据报,这是基于 DHT 的应用程序(例如 emule,bittorrent)中的正常行为)?
I wonder what's the source port of the messages in both cases? If it's a random port decided by system calls
您通常使用绑定到特定本地端口的套接字 (POSIX bind()
)。该本地端口将同时作为传出消息的源端口和传入消息的目标端口。请注意,对于 UDP,您可能希望使用 POSIX sendmsg()
或 sendto()
调用而不是 send()
.
这对于 DHT 协议很重要,因为其他节点会根据您的源端口推断您正在侦听的端口,并将其存储在它们的路由表中。
至于具体的端口号,原则上你可以为你的DHT使用固定的端口号,这意味着其他节点不必推断监听端口,因为它们知道它是固定的。
但最好有一些灵活性,这样可以避免端口冲突。因此,节点通常应该可以自由选择任何端口,然后通过该端口执行所有发送 和 接收操作。
此外,由于 IPv6 变得越来越普遍,您需要 将套接字绑定到主机上的一个特定地址 ,因为 v6 通常为每个主机提供多个地址并监听多个接口和从不同 IP 发送消息将使您对其他 DHT 节点(不断变化的 IP 地址)显得不可靠。 IE。如果可以避免,请不要绑定到任何本地地址(0.0.0.0
或 ::0
)。
找出哪个本地地址用于默认路由并绑定到该地址。
创建一个UDP套接字并绑定到一个端口,然后我们仍然可以使用这个套接字发送消息。 UDP 是对称的,不像 TCP。
udp-socket
无需绑定或连接;如果未绑定,udp-send-to
将其绑定到随机本地端口。
(udp-send-to udp-socket
hostname
port-no
bstr
[ start-pos
end-pos]) → void
udp-socket : udp?
hostname : string?
port-no : port-number?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
将(subbytes bytes start-pos end-pos)作为数据报从未连接的 udp-socket 发送到端口 port-no
上远程机器 hostname-address
的套接字。 udp-socket
不需要绑定或连接;如果未绑定,udp-send-to
将其绑定到随机本地端口。如果套接字的传出数据报队列太满而无法支持发送,udp-send-to
阻塞直到数据报可以排队。
我正在做一个 DHT 的小型演示项目(仅限 p2p 路由,如 Chord、Pastry 等),我对 P2P 网络中的传输细节感到困惑。
假设所有peer都使用UDP进行通信,端口为10050,固定不变,那么考虑两种典型情况:
- A 可能会向 B 发送 "JOIN" 消息。
- 此外,B 可能会根据 p2p 性质向 A 发送 "JOIN" 消息(或其他消息)。
情况一,报文的目的端口必须是10050;
情况2,报文的目的端口必须是10050;
我想知道两种情况下消息的源端口是什么?如果它是由系统调用决定的随机端口,DHT 协议栈需要处理 10050 和随机端口 上的数据报,这是基于 DHT 的应用程序(例如 emule,bittorrent)中的正常行为)?
I wonder what's the source port of the messages in both cases? If it's a random port decided by system calls
您通常使用绑定到特定本地端口的套接字 (POSIX bind()
)。该本地端口将同时作为传出消息的源端口和传入消息的目标端口。请注意,对于 UDP,您可能希望使用 POSIX sendmsg()
或 sendto()
调用而不是 send()
.
这对于 DHT 协议很重要,因为其他节点会根据您的源端口推断您正在侦听的端口,并将其存储在它们的路由表中。
至于具体的端口号,原则上你可以为你的DHT使用固定的端口号,这意味着其他节点不必推断监听端口,因为它们知道它是固定的。
但最好有一些灵活性,这样可以避免端口冲突。因此,节点通常应该可以自由选择任何端口,然后通过该端口执行所有发送 和 接收操作。
此外,由于 IPv6 变得越来越普遍,您需要 将套接字绑定到主机上的一个特定地址 ,因为 v6 通常为每个主机提供多个地址并监听多个接口和从不同 IP 发送消息将使您对其他 DHT 节点(不断变化的 IP 地址)显得不可靠。 IE。如果可以避免,请不要绑定到任何本地地址(0.0.0.0
或 ::0
)。
找出哪个本地地址用于默认路由并绑定到该地址。
创建一个UDP套接字并绑定到一个端口,然后我们仍然可以使用这个套接字发送消息。 UDP 是对称的,不像 TCP。
udp-socket
无需绑定或连接;如果未绑定,udp-send-to
将其绑定到随机本地端口。
(udp-send-to udp-socket
hostname
port-no
bstr
[ start-pos
end-pos]) → void
udp-socket : udp?
hostname : string?
port-no : port-number?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
将(subbytes bytes start-pos end-pos)作为数据报从未连接的 udp-socket 发送到端口 port-no
上远程机器 hostname-address
的套接字。 udp-socket
不需要绑定或连接;如果未绑定,udp-send-to
将其绑定到随机本地端口。如果套接字的传出数据报队列太满而无法支持发送,udp-send-to
阻塞直到数据报可以排队。