所谓的UDP "connection"



我的理解是UDP不形成连接;它只是盲目地发送数据包。然而,当我运行时

nc -u -l 10002

nc -u 127.0.0.1 10002

同时(因此可以在终端之间来回发送消息(,lsof报告两个打开的UDP连接:

nc ... UDP localhost:10002->localhost:35311 
nc ... UDP localhost:35311->localhost:10002 

如果我打开第三个终端并再次执行nc -u 127.0.0.1 10002,以向原始侦听器发送另一条消息,则侦听器不会接收(或至少确认(该消息,这表明它确实与特定连接绑定
如果我像这样用Java实现UDP echo服务器,并做同样的事情(在10001上(,我会得到

java ... UDP *:10001
nc ... UDP localhost:52295->localhost:10001

也就是说,Java只是在监听10001,但nc已经形成了连接。

根据我对UDP的理解,我希望双方的行为都像Java版本。怎么回事?我可以让Java版本做nc正在做的任何事情吗?这样做有好处吗?

我使用的是Ubuntu 20.04.3 LTS。

UDP套接字可以连接(在调用connect之后(,也可以不连接。在第一种情况下,套接字只能与连接的对等体交换数据,而在第二种情况下它可以与任意对等体交换信息。您在lsof中看到的是套接字是否已连接。

我的理解是UDP不会形成连接;它只是盲目地发送数据包。

这是术语连接的不同含义。TCP具有总是";真实的";连接,即具有明确开始(基于SYN的握手(和结束(基于FIN的拆卸(的两个端点之间的关联。用于数据交换的TCP套接字因此总是连接的。

UDP也可以在两个端点之间具有关联,即它可以具有连接的套接字。然而,并没有明确的设置和拆除这样的连接。而且UDP套接字不需要连接。因此,通过查看流量,无法确定连接的UDP套接字是在使用中还是未连接。

我可以让Java版本做nc正在做的任何事情吗?

是的,请参阅Java的UDPDatagramSocket.connect((做什么?.

这样做有好处吗?

未连接的UDP套接字将从任何对等端接收数据,应用程序必须检查每个接收到的数据报的来源以及是否应接受这些数据报。连接的UDP套接字将只接收来自连接的对等方的数据,即不需要在应用程序中进行检查。

除此之外,如果使用不同的套接字与不同的对等方进行通信,它可能会更好地扩展。但是,如果每个对等端只交换很少的数据包,和/或需要同时与许多对等端通信,那么使用多个连接的套接字而不是一个未连接的套接字可能意味着太多的开销。

最新更新