C# UDP结婚搜丢包问题

lovezn0424 2010-11-02 07:52:16
先说说 机器之间配置吧:

总共有个8个机器给 我发数据。给我指定的同一个端口发送数据。

其中1,2,3,4机基本上同时给我发送数据。

发送一帧数据大小大概为8k-9k之间。
wireshark抓包看 可以接收到数据。
当我们程序中却丢包。

我的程序大概设计思路这样。

Udp接受程序,先把接受的数据放到缓存里,然后隔1ms就往
应用传送。接着应用先把传送过来的数据放到自己缓存区里。
初始化操作如下:
IPAddress localIPAddress = IPAddress.Parse(localIP);
IPEndPoint localIPEndPoint = new IPEndPoint(localIPAddress, localPort);

udpReceiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpReceiveSocket.Bind(localIPEndPoint);//绑定本机IP端口
receiveDataThread = new Thread(ReceiveData);
receiveDataThread.IsBackground = true;
receiveDataThread.Priority = ThreadPriority.AboveNormal;
receiveDataThread.Start();


然后接受进程
byte[] receiveBuff = new byte[this.receiveBufferSize]; //定义接收缓冲区
IPEndPoint sourceIPEndPoint= new IPEndPoint(IPAddress.Any, 0);
EndPoint sourceEndPoint = (EndPoint)sourceIPEndPoint;

Int32 dataLen = udpReceiveSocket.ReceiveFrom(receiveBuff, ref sourceEndPoint);
DateTime revDateTime = DateTime.Now;//记录接收到数据时的日期时间
if (dataLen > 0)
{
UdpReceiveDataClass udpRecvDataCls = new UdpReceiveDataClass();
udpRecvDataCls.SourceIP = ((IPEndPoint)sourceEndPoint).Address.ToString();
udpRecvDataCls.Port = ((IPEndPoint)sourceEndPoint).Port;
udpRecvDataCls.RecvTime = revDateTime;
udpRecvDataCls.RevDataBytes = new byte[dataLen];
Array.Copy(receiveBuff, udpRecvDataCls.RevDataBytes, dataLen);

lock (udpReceiveDataClassListLocker)
{
udpReceiveDataClassList.Add(udpRecvDataCls);
}
}
else
{
//添加测试相关代码
}
...全文
217 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovezn0424 2010-11-10
  • 打赏
  • 举报
回复
哎。
看来真的没有好解决的办法了呀。
lovezn0424 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 shalen520 的回复:]
应该自己设计应用层协议来保证可靠的udp通信
[/Quote]

这样是最好的。
问题是 如果增加应用层的协议来保证的话,
又增加系统的复杂度,以及成本。
从上层来看这样是不允许的。

现在真愁这个事情呢。


通过记录数据来分析。
经过一段时间后,
就会丢包。
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lovezn0424 的回复:]
若丢包不怎么频繁,也能接受,比如说30分 中 丢包1次 2 次之类的。
[/Quote]

如果能控制30分之1,那么还算不可靠?只要连续发两次不久变成900分之1了嘛!

所以不可能。就算80%的包都丢了也是运行中正常,人家udp没有bug,而你硬要它达到什么30分之一的丢包率才是设计bug,因为udp根本不管控制接收端是否收到这个义务。
vpoint2009 2010-11-03
  • 打赏
  • 举报
回复
tcp异步传输?话说tcp自称可靠,我怎么试验得不稳定啊..。
ajq1989 2010-11-03
  • 打赏
  • 举报
回复
减少丢包率
1、每个UDP包的体积小,小于460个字节,减少分片,从一定程度上可以减少丢包
2、提高接受缓冲区的大小,把接受缓冲设为10K以上
3、采用一问一答,每个包编号,自己采用一套机制,但是这样就太复杂。

mjp1234airen4385 2010-11-03
  • 打赏
  • 举报
回复
dup丢包才是正常的,不丢才不正常。
一定要做好校验,丢了以后再发送。
可以考虑使用rtp。
rtp:一种基于udp的协议。做了校验、重发等动作。
比udp复杂,需要花费精力去研究的。
mjp1234airen4385 2010-11-03
  • 打赏
  • 举报
回复
udp不丢包,就不是udp。
comon1981 2010-11-03
  • 打赏
  • 举报
回复
帮顶,我最近也在搞 UDP采集实时数据的东西,现在数据量不大还比较稳定,同担心点数增加很大后会出现问题啊
lovezn0424 2010-11-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 beargo 的回复:]
做到谁发送谁检查是否收到包即可...当A发一个包后..间隔1秒或长点时间还没收到回包时,视为丢包.重新发送请求.
[/Quote]

不过这不现实,因为现在系统中,我这软件只是实时记录下数据而已。
若丢包不怎么频繁,也能接受,比如说30分 中 丢包1次 2 次之类的。
lovezn0424 2010-11-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sp1234 的回复:]
udp丢包50%也是很正常的,这根本就不是可靠通信。想要可靠(但也不是100%不丢包),应该使用tcp。
[/Quote]

如果在一个稳定的网络状态下,应该不出现这个问题。

现在的问题是,在数据量少的时候,不出现该问题。

只有在数据量增加到每机 8k数据量下 才会出现问题。

因而我觉得就是在数据提取的过程中效率不够才造成的。
beargo 2010-11-03
  • 打赏
  • 举报
回复
做到谁发送谁检查是否收到包即可...当A发一个包后..间隔1秒或长点时间还没收到回包时,视为丢包.重新发送请求.
guyehanxinlei 2010-11-03
  • 打赏
  • 举报
回复
Friendly Up!
chaozi_249 2010-11-03
  • 打赏
  • 举报
回复
赶紧换成Tcp,udp不可靠协议经常丢。
  • 打赏
  • 举报
回复
udp丢包50%也是很正常的,这根本就不是可靠通信。想要可靠(但也不是100%不丢包),应该使用tcp。
三岁、就很帅 2010-11-03
  • 打赏
  • 举报
回复
帮顶 等高人 接分
熙风 2010-11-03
  • 打赏
  • 举报
回复
解决不了。

帮忙顶顶···········
redshiliu 2010-11-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 beargo 的回复:]
做到谁发送谁检查是否收到包即可...当A发一个包后..间隔1秒或长点时间还没收到回包时,视为丢包.重新发送请求.
[/Quote]

这样还不如直接用tcp/ip
yilaozhuang 2010-11-03
  • 打赏
  • 举报
回复
udp有这么不好啊,以后要注意了
shalen520 2010-11-03
  • 打赏
  • 举报
回复
应该自己设计应用层协议来保证可靠的udp通信
taolinsen 2010-11-03
  • 打赏
  • 举报
回复
环境允许,项目允许。
强烈建议使用TCP
加载更多回复(2)
下载代码方式:https://pan.quark.cn/s/dd3561eca308 在软件开发领域,面向对象编程(OOP)是一种普遍采纳的结构化方法,它使得开发者能够借助模拟现实环境中的实体和关系来构建软件系统。在本案例中,我们观察到的是一个关于借助抽象类来执行不同几何图形面积求解的实践应用。现在,让我们详细分析这一议题。 标题 "应用抽象类计算面积" 清晰地表明我们将要讨论一个抽象类,此类设定了一个用于测量图形面积的标准函数,但并未提供实际的执行过程。抽象类在诸如C#或Java等编程语言中通常借助`abstract`修饰符进行声明,它们无法直接创建对象实例,仅能作为其他类的基础模板。 描述部分提及的"图形界面应用"暗示这是一个基于视觉用户界面(GUI)的系统,可能运用了.NET Framework的Windows Forms或WPF技术,或者是Java平台的Swing或JavaFX框架。在这样环境下,用户能够通过视觉元素与这些几何体进行互动,例如输入相关尺寸并观看到计算得出的面积值。 抽象类“几何体”内嵌了“计算面积”这一抽象函数。在代码层面,这可以被表述为: ```csharp public abstract class GeometricShape { public abstract double CalculateArea(); } ``` 随后,有三个派生类:圆(Circle)、矩形(Rectangle)和三角形(Triangle),它们各自提供了这个抽象函数的具体实现。比如,圆的面积是通过π乘以半径的平方得到的,矩形的面积是长和宽的乘积,而三角形的面积可能是底乘以高再除以2的结果。这些类将提供具体实现来计算它们各自的面积: ```csharp p...

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧