UDP 发送和接收套接字行为

本文关键字:套接字 UDP | 更新日期: 2023-09-27 18:35:04

我正在编写一个程序,该程序将首先向服务器进行身份验证,然后通过UDP发送和接收消息。在发送和接收消息时,我还需要保持与服务器的连接,因此我需要定期向服务器发送 KeepAlive 并接收来自服务器的响应。

我知道可以同时在同一套接字上发送和接收数据包,但我担心这种情况需要一段时间来构建用于发送的数据包,在此期间,服务器向我发送了两条消息。

  1. 当我调用 receive() 时,第二条消息会覆盖第一条消息吗?
  2. 我要完成的任务设置两个 UDP 套接字是最佳做法吗? 一个套接字用于发送,一个套接字用于接收。

谢谢莱 克 斯

UDP 发送和接收套接字行为

不幸的是,您说您无法控制的服务器需要 UDP 具有身份验证方案。这是一个严重的安全问题,因为攻击者相对容易伪装成与经过身份验证的客户端相同的 UDP 端点。

就您的具体问题而言:

  1. 在理想情况下,如果服务器在您尝试接收任何数据报(消息)之前向您发送了两个数据报(消息),您仍将按照发送的顺序收到两个数据报,因为操作系统已经缓冲了它们并按顺序将它们呈现给您。

问题是这不是一个完美的世界,尤其是当您处理UDP时。UDP 有三个重要的限制:

  • 不保证任何给定数据报的交付。任何数据报都可能随时丢失。
  • 不保证交货顺序。数据报的接收顺序不一定与发送顺序相同。
  • 不保证交付的唯一性。任何给定的数据报都可以多次传送。

因此,如果服务器发送第二个数据报,如果您尚未收到第一个数据报,则可能会丢失,而且无论如何第一个数据报都可能丢失。您不能保证任何数据报都会发送给您。

现在,还有一个问题是收到数据报后如何处理它。不幸的是,从您的问题中不清楚这是否是您所问的一部分。但自然地,一旦对ReceiveFrom()的调用完成(或者Receive()如果你在UDP Socket上使用过Connect()并且你手头有数据报),这完全取决于你的代码如何处理这个问题以及以前接收的数据是否被覆盖。

  1. 创建两个单独的 UDP Socket实例不是最佳做法,一个用于处理接收,另一个用于处理发送。不仅没有必要,您还必须具有某种机制,以便服务器了解两个不同的远程端点实际上代表同一个客户端(因为它们通常具有不同的端口号,即使您保证它们位于相同的 IP 地址上),或者Socket您必须通过使用"重用地址"选项(这是一种允许相同端口由两种不同的Sockets,但这会导致各种其他问题)。
使用相同的

Socket实例进行接收和发送是完全可以的,事实上,这就是您应该使用它的方式。最佳做法是这样做。