关于p2p应用中的UDP端口

About UDP port in p2p application

我正在做一个 DHT 的小型演示项目(仅限 p2p 路由,如 Chord、Pastry 等),我对 P2P 网络中的传输细节感到困惑。

假设所有peer都使用UDP进行通信,端口为10050,固定不变,那么考虑两种典型情况:

  1. A 可能会向 B 发送 "JOIN" 消息。
  2. 此外,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 阻塞直到数据报可以排队。