简体   繁体   English

UDP发送和接收套接字行为

[英]Udp Send and Receive socket behavior

I am writing a program which will first authenticate to a server then send and receive messages through UDP. 我正在编写一个程序,该程序将首先对服务器进行身份验证,然后通过UDP发送和接收消息。 While sending and receiving messages, I also need to maintain the connection to the server, so I need to periodically send KeepAlive to the server and receive response from the server. 在发送和接收消息时,我还需要维护与服务器的连接,因此我需要定期将KeepAlive发送到服务器并从服务器接收响应。

I understand it is possible to send and receive packets on the same socket at the same time, but I am concerned about the scenario where I take a while to build a packet for sending, and during that time, the server sent me two messages. 我知道可以在同一时间在同一套接字上发送和接收数据包,但是我担心这种情况:我花了一些时间来构建要发送的数据包,在此期间,服务器向我发送了两条消息。

  1. When I call receive(), does the second message overwrites the first message? 当我调用receive()时,第二条消息是否会覆盖第一条消息?
  2. Is it the best practice to set up two UDP sockets for what I am trying to accomplish? 为要完成的任务设置两个UDP套接字是最佳实践吗? one socket for sending and one socket for receiving. 一个用于发送的插槽和一个用于接收的插槽。

Thank you, Lex 谢谢Lex

It is unfortunate that the server, which you say you have no control over, requires UDP and has an authentication scheme. 不幸的是,您说您无法控制的服务器需要UDP 具有身份验证方案。 This is a serious security problem, because it is relatively easy for an attacker to pretend to be the same UDP end point as your client which has been authenticated. 这是一个严重的安全问题,因为攻击者相对容易地假装与已通过身份验证的客户端相同的UDP端点。

As far as your specific questions go: 至于您的具体问题:

  1. In a perfect world, if the server sends you two datagrams (messages) before you have tried to receive any, you will still receive both datagrams, in the order in which they were sent, because the OS has buffered them and presents them both to you in order. 在理想的情况下,如果服务器在尝试接收任何数据报之前向您发送了两个数据报(消息),则您仍将按照发送它们的顺序接收两个数据报,因为操作系统已将它们缓冲并提供给为了你。

The problem is that it's not a perfect world, and especially when you are dealing with UDP. 问题在于,这不是一个完美的世界,尤其是在处理UDP时。 UDP has three significant limitations: UDP具有三个重要限制:

  • Delivery of any given datagram is not guaranteed. 不保证任何给定数据报的传送。 Any datagram may be lost at any time. 任何数据报都可能随时丢失。
  • Order of delivery is not guaranteed. 不能保证交货顺序。 Datagrams are not necessarily received in the same order in which they were sent. 数据报不一定按发送时的相同顺序接收。
  • Uniqueness of delivery is not guaranteed. 不能保证交付的唯一性。 Any given datagram may be delivered more than once. 任何给定的数据报可能会被多次传递。

So not only is it possible that if the server sends a second datagram, the first one may be lost if you have not received it yet, the first one may be lost in any case . 因此,如果服务器发送第二个数据报,不仅有可能会丢失第一个数据报(如果您尚未收到),那么无论如何第一个数据报都可能会丢失。 You have no guarantee that any datagram will be delivered to you. 您不能保证任何数据报都会被交付给您。

Now, there is also the issue of what you do with the datagram once you have received it. 现在,也有你与数据报做什么,一旦你已经收到了这个问题。 Unfortunately, it's not clear from your question whether this is part of what you're asking about. 不幸的是,从您的问题中尚不清楚这是否是您要问的内容的一部分。 But naturally, once the call to ReceiveFrom() completes (or Receive() if you have used Connect() on the UDP Socket ) and you have the datagram in hand, it's entirely up to your code how this is handled and whether previously-received data is overwritten or not. 但是自然地,一旦对ReceiveFrom()的调用完成(或者,如果您已经在UDP Socket上使用了Connect()Receive()的调用)并且您拥有了数据报,这完全取决于您的代码如何处理以及是否先前-接收的数据是否被覆盖。

  1. It is not best practices to create two separate UDP Socket instances, one to handle receiving and one to handle sending. 创建两个单独的UDP Socket实例不是一个最佳实践,一个实例用于处理接收,另一个实例用于发送。 Not only is it unnecessary, you would have to either have some mechanism for the server to understand that two different remote endpoints actually represent the same client (since they would normally have different port numbers, even if you guaranteed they were on the same IP address), or you would have to abuse the Socket by using the "reuse address" option (which is a way to allow the same port to be used by two different Sockets , but which leads to all kinds of other issues). 不仅是没有必要的,您还必须具有某种机制让服务器理解两个不同的远程端点实际上代表同一客户端(因为即使保证它们位于相同的IP地址上,它们通常具有不同的端口号) ),否则您将不得不使用“重用地址”选项来滥用Socket (这是一种允许两个不同的Sockets使用同一端口的方法,但这会导致其他各种问题)。

It is perfectly fine to use the same Socket instance for both receiving and sending, and in fact this is how you're expected to use it. 将相同的Socket实例用于接收和发送都很好,实际上,这就是您期望使用它的方式。 The best practice is to do it that way. 最佳做法是这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM