Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 了解如何通过UDP可靠地发送较大的数据块_.net_Sockets_Networking_Udp - Fatal编程技术网

.net 了解如何通过UDP可靠地发送较大的数据块

.net 了解如何通过UDP可靠地发送较大的数据块,.net,sockets,networking,udp,.net,Sockets,Networking,Udp,这些年来,我使用TCP做了很多事情,并且非常了解它。我现在需要使用UDP 短版本:服务器允许少量客户端(5-10)连接。服务器正在运行模拟。客户端应该能够更新模拟的参数,并查看模拟结果的(子集) 在这种情况下,定时(参数更改时)非常重要,请求更改的客户端与正在执行的客户端之间的延迟必须尽可能低 我已经,但我仍然没有“明白” 有人能证实/否认我的理解吗 数据报存储在单个数据包中 我能可靠发送的最大有效负载是506字节(576MTU-60IP头-8UDP头) 发送超过此值可能会导致碎片 碎片不是在

这些年来,我使用TCP做了很多事情,并且非常了解它。我现在需要使用UDP

短版本:服务器允许少量客户端(5-10)连接。服务器正在运行模拟。客户端应该能够更新模拟的参数,并查看模拟结果的(子集)

在这种情况下,定时(参数更改时)非常重要,请求更改的客户端与正在执行的客户端之间的延迟必须尽可能低

我已经,但我仍然没有“明白”

有人能证实/否认我的理解吗

  • 数据报存储在单个数据包中
  • 我能可靠发送的最大有效负载是506字节(576MTU-60IP头-8UDP头)
  • 发送超过此值可能会导致碎片
  • 碎片不是在较低的级别上处理的,需要我重新组合数据报(对此不确定-如果它是自动处理的,为什么我会关心碎片?)
  • 我需要实现自己的ACK/限制机制
所以。。。如果我想从客户端向服务器发送(比如)800字节的数据,我需要:

  • 确定要使用的任意“协议”id,该id由客户端和服务器之间通用的字节(2)表示,用于过滤不适用于我的应用程序的消息
客户
  • 创建一个随机消息id
  • 将数据一分为二,添加消息id和全局序列,以便它们可以在另一端重新连接
  • 根据内存中的某个序列id记录数据
  • 将它们发送到服务器
  • 如果在给定的时间间隔内(比如RTT*3)没有收到Ack,则重新发送该数据包
服务器
  • 在模拟回路内部,检查(非阻塞)套接字上是否有消息
  • 如果是这样,立即发送回一个包含序列Id的ACK的新数据包(实际上,为了减少ACK数据包丢失,我应该确认最近30个左右接收到的数据包)
  • 将数据包存储在内存中,直到收到下半部分
  • 将两者结合起来处理有效载荷
对于向另一个方向发送的消息,我需要反向执行完全相同的操作

我忍不住觉得自己遗漏了什么,也不太理解数据包碎片的含义。有人能澄清/指出更好的资源吗

数据报存储在单个数据包中

没有

我能可靠发送的最大有效负载是506字节(576MTU-60IP) 报头(8个UDP报头)

“可靠发送”指不同级别的不同内容

发送超过此值可能会导致碎片

这是事实

碎片不是在较低级别处理的,需要我 重新组合数据报(不确定是否已处理) 当然,我为什么要关心碎片?)

取决于你的水平。在应用程序级别,数据报要么全部接收,要么根本不接收

子问题:太宽泛了,但听起来你应该改用TCP

  • 数据报存储在单个数据包中
不一定

  • 我能可靠发送的最大有效负载是506字节(576MTU-60IP头-8UDP头)
不对。IP头是20字节,而不是60字节,因此总头是28字节。这就剩下576-28=548,但通常是534

  • 发送超过此值可能会导致碎片

  • 碎片不是在较低的级别上处理的,需要我重新组合数据报(对此不确定-如果它是自动处理的,为什么我会关心碎片?)
不对。碎片完全在IP级别处理。UDP中的碎片问题是,对于丢失的碎片没有ACK/重新传输机制,因此一个丢失的碎片意味着整个数据报丢失。您看到的要么是整个UDP数据报,要么什么都没有

  • 我需要实现自己的ACK/限制机制

对。W.R.Stevens,《Unix网络编程》第一卷中给出了一个简单的确认/重试方案。

如果这一方案过于宽泛,则表示歉意-不幸的是,我正在处理未知的问题。关于TCP,你可能是对的。基本上,我想要的是具有较低延迟的TCP。显然那是白日梦,我需要妥协。从服务器向客户端传递状态可能是有损的,不会产生有害影响。从客户端到服务器必须“尽快”到达。您是否介意对您的答案进行一点扩展,以解释“否/经济”回答?感谢you@Basic“具有较低延迟的TCP”只能指“没有流量控制、ACK/重传、排序、慢启动、拥塞避免等的TCP”,即您实际需要的所有内容。它不是自动处理的。默认情况下,Socket.DontFragment属性为true。您无法返回ICMP消息,该消息告诉您数据包太大。如果将其设置为false,则需要解决使数据包无序并仍能正确识别它们的问题。可靠的UDP以前已经做过多次,最好使用。@HansPassant感谢链接(以及删除答案中的信息)。那个图书馆看起来正是我需要的。如果我可以避免重新发明轮子,我很乐意这样做。UDP头是28字节,而不是68字节@HansPassant它由IP层自动处理,包括片段排序。UDP碎片的问题不是碎片排序,而是缺少重新传输,这意味着丢失的碎片==丢失的数据报。感谢您提供的信息,但是我读到的20-60的re:IP头是可能的<代码>由于IPv4标头可能包含可变数量的选项,因此此字段指定标头的大小(这也与o一致)