Udp 发送和接收套接字行为 [英] Udp Send and Receive socket behavior

查看:41
本文介绍了Udp 发送和接收套接字行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a program which will first authenticate to a server then send and receive messages through 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.

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

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. 当我调用receive() 时,第二条消息会覆盖第一条消息吗?
  2. 为我要完成的任务设置两个 UDP 套接字是最佳做法吗?一个用于发送的套接字和一个用于接收的套接字.

谢谢,莱克斯

推荐答案

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

It is unfortunate that the server, which you say you have no control over, requires UDP and has an authentication scheme. 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.

就您的具体问题而言:

  1. 在完美的世界中,如果服务器在您尝试接收任何数据报(消息)之前向您发送了两个数据报(消息),您仍然会按照发送的顺序接收这两个数据报,因为操作系统已将它们缓冲并呈现按顺序发给你.

问题在于它不是一个完美的世界,尤其是当您处理 UDP 时.UDP 具有三个重大限制:

The problem is that it's not a perfect world, and especially when you are dealing with UDP. UDP has three significant limitations:

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

因此,如果服务器发送第二个数据报,第一个可能会丢失(如果您还没有收到),那么第一个可能会丢失在任何情况下.您无法保证任何数据报都会发送给您.

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.

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

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.

  1. 创建两个单独的 UDP Socket 实例不是最佳实践,一个用于处理接收,另一个用于处理发送.不仅没有必要,您还必须有某种机制让服务器了解两个不同的远程端点实际上代表同一个客户端(因为它们通常具有不同的端口号,即使您保证它们位于相同的 IP 地址上),或者您将不得不通过使用重用地址"选项来滥用 Socket(这是一种允许两个不同的 Sockets 使用相同端口的方法,但这会导致各种其他问题).
  1. It is not best practices to create two separate UDP Socket instances, one to handle receiving and one to handle sending. 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).

使用相同的 Socket 实例进行接收和发送是完全没有问题的,事实上这就是您期望使用它的方式.最好的做法是这样做.

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. The best practice is to do it that way.

这篇关于Udp 发送和接收套接字行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆