Udp发送和接收套接字行为

时间:2014-12-23 18:10:20

标签: c# sockets udp

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

我知道可以同时在同一个套接字上发送和接收数据包,但我担心我需要一段时间来构建数据包以便发送,在此期间,服务器发送给我两条消息。

  1. 当我调用receive()时,第二条消息是否会覆盖第一条消息?
  2. 为我想要完成的工作设置两个UDP套接字是最佳做法吗?一个插座用于发送,一个插座用于接收。
  3. 谢谢你, 莱克斯

1 个答案:

答案 0 :(得分:2)

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

就具体问题而言:

  1. 在一个完美的世界中,如果服务器在您尝试接收任何数据报之前向您发送两个数据报(消息),您仍将按发送顺序接收这两个数据报,因为操作系统已缓存它们并呈现他们都按顺序给你。
  2. 问题在于它不是一个完美的世界,特别是当你处理UDP时。 UDP有三个重要的局限性:

    • 无法保证交付任何给定的数据报。任何数据报都可能随时丢失。
    • 不保证交货顺序。数据报不一定按照发送顺序接收。
    • 无法保证交付的独特性。任何给定的数据报都可以多次传送。

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

    现在,还有一个问题是,一旦你 收到数据报,你会对数据报做些什么。不幸的是,从您的问题中不清楚这是否是您所询问的内容的一部分。但很自然,一旦对ReceiveFrom()的调用完成(或Receive(),如果您在UDP Connect()上使用了Socket)并且您手头有数据报,则完全取决于您的代码如何处理此代码以及先前收到的数据是否被覆盖。

    1. 创建两个单独的UDP Socket实例是最佳做法,一个用于处理接收,另一个用于处理发送。不仅没有必要,你必须要有一些机制让服务器理解两个不同的远程端点实际上代表同一个客户端(因为它们通常会有不同的端口号,即使你保证它们在同一个IP地址上) ),或者您必须使用“重用地址”选项滥用Socket(这是允许两个不同Sockets使用相同端口的方法,但这会导致各种类型其他问题)。
    2. 对于接收和发送使用相同的Socket实例是完全没问题的,事实上这就是你期望使用它的方式。最好的做法是这样做。