C#实现UDP数据包大文件分包传输和接收组包

UDP的设计是基于"datagram",也就是它假设你发送的每个数据包都能包含在
【菜科解读】
如果需要使用UDP传输较大数据,例如传输10M的图片,这突破了UDP的设计原则。
UDP的设计是基于"datagram",也就是它假设你发送的每个数据包都能包含在单一的包内。
并且设定UDP数据包的最大长度受基础网络协议的限制。
UDP数据包的理论最大长度限制是 65535 bytes,这包含 8 bytes 数据包头和 65527 bytes 数据。
但如果基于IPv4网络传输,则还需减去 20 bytes 的IP数据包头。
则单一的UDP数据包可传输的数据最大长度为:
MaxUdpDataLength = 65535 - 8 - 20 = 65507 bytes
这就需要实现UDP包的分包传输和接收组包功能。
分包功能
1 ///
2 /// UDP数据包分割器 3 /// 4 public static class UdpPacketSplitter 6 /// 7 /// 分割UDP数据包 8 /// 9 ///UDP数据包所持有的序号10 ///
被分割的UDP数据包11 ///
分割块的长度12 /// 13 /// 分割后的UDP数据包列表14 /// 15 public static ICollection Split(long sequence, byte[] datagram, int chunkLength)17 if (datagram == null)18 throw new ArgumentNullException("datagram");20 List packets = new List();22 int chunks = datagram.Length / chunkLength;23 int remainder = datagram.Length % chunkLength;24 int total = chunks;25 if (remainder > 0) total++;27 for (int i = 1; i 0)35 int length = datagram.Length - (chunkLength * chunks);36 byte[] chunk = new byte[length];37 Buffer.BlockCopy(datagram, chunkLength * chunks, chunk, 0, length);38 packets.Add(new UdpPacket(sequence, total, total, chunk, length));41 return packets;43 }
发送分包
1 private void WorkThread()
2 { 3 while (IsRunning) 5 waiter.WaitOne(); 6 waiter.Reset(); 8 while (queue.Count > 0)10 StreamPacket packet = null;11 if (queue.TryDequeue(out packet))13 RtpPacket rtpPacket = RtpPacket.FromImage(14 RtpPayloadType.JPEG, 15 packet.SequenceNumber, 16 (long)Epoch.GetDateTimeTotalMillisecondsByYesterday(packet.Timestamp),17 packet.Frame);19 // max UDP packet length limited to 65,535 bytes20 byte[] datagram = rtpPacket.ToArray(); 21 packet.Frame.Dispose();23 // split udp packet to many packets 24 // to reduce the size to 65507 limit by underlying IPv4 protocol25 ICollection udpPackets 26 = UdpPacketSplitter.Split(27 packet.SequenceNumber, 28 datagram, 29 65507 - UdpPacket.HeaderSize);30 foreach (var udpPacket in udpPackets)32 byte[] udpPacketDatagram = udpPacket.ToArray();33 // async sending34 udpClient.BeginSend(35 udpPacketDatagram, udpPacketDatagram.Length,36 packet.Destination.Address,37 packet.Destination.Port,38 SendCompleted, udpClient);43 }接收组包功能
1 private void OnDatagramReceived(object sender, UdpDatagramReceivedEventArgs e)
2 { 3 try 5 UdpPacket udpPacket = UdpPacket.FromArray(e.Datagram); 7 if (udpPacket.Total == 1) 9 RtpPacket packet = new RtpPacket(udpPacket.Payload, udpPacket.PayloadSize);10 Bitmap bitmap = packet.ToBitmap();11 RaiseNewFrameEvent(12 bitmap, Epoch.GetDateTimeByYesterdayTotalMilliseconds(packet.Timestamp));14 else16 // rearrange packets to one packet17 if (packetCache.ContainsKey(udpPacket.Sequence))19 List udpPackets = null;20 if (packetCache.TryGetValue(udpPacket.Sequence, out udpPackets))22 udpPackets.Add(udpPacket);24 if (udpPackets.Count == udpPacket.Total)26 packetCache.TryRemove(udpPacket.Sequence, out udpPackets);28 udpPackets = udpPackets.OrderBy(u => u.Order).ToList();29 int rtpPacketLength = udpPackets.Sum(u => u.PayloadSize);30 int maxPacketLength = udpPackets.Select(u => u.PayloadSize).Max();32 byte[] rtpPacket = new byte[rtpPacketLength];33 foreach (var item in udpPackets)35 Buffer.BlockCopy(36 item.Payload, 0, rtpPacket, 37 (item.Order - 1) * maxPacketLength, item.PayloadSize);40 RtpPacket packet = new RtpPacket(rtpPacket, rtpPacket.Length);41 Bitmap bitmap = packet.ToBitmap();42 RaiseNewFrameEvent(43 bitmap, 44 Epoch.GetDateTimeByYesterdayTotalMilliseconds(packet.Timestamp));46 packetCache.Clear();50 else52 List udpPackets = new List();53 udpPackets.Add(udpPacket);54 packetCache.AddOrUpdate(55 udpPacket.Sequence, 56 udpPackets, (k, v) => { return udpPackets; });60 catch (Exception ex)62 RaiseVideoSourceExceptionEvent(ex.Message);64 } 实现,UDP,数据,包大,文件,分包,传输,和,接收,十八世纪的意大利做干了哪些事情 为什么能够实现统一呢
那么,这究竟是怎么回事呢?下面我们就一起前往查看一番。
首先,让我们先将目光移到公元1860年5月6日的早晨,就会发现,在意大利热那亚城外的港口,有两艘旧船正稳稳地停着,似乎在等待着什么重要任务。
而此时,1000多名身穿红衬衫,头戴阔边帽的意大利人则迅速登上了这两艘船。
接着,只见有一个中年人在大声呼喊:“为解放西西里岛的同胞,为意大利的统一,前进!”然后,轮船就像飞一样,消失在了漆黑的海洋里。
那么,这又是咋回事呢?原来那个高喊口号的中年人叫加里波第。
他生于1807年,是一个水手出身。
青年的时候就由于在反对外国占领者的过程中失败而逃到了拉丁美洲,然后,在1848年回国以后,就成为了意大利统一运动的领导者。
要知道,统一对于当时的意大利而言非常重要。
因为当时的意大利至少也分裂为了数个小国。
而北部的几个小国则被奥地利占领,南部的西西里王国则被西班牙占领,中部地区则归属于教皇管理,可以说是。
因此,当西西里王国的许多爱国老百姓听闻有意大利统一运动的武装力量前来的时候,都感到格外高兴。
他们马上就兴高采烈地到码头迎接,而见面之后,便开始商量对策。
但就在此时,炮声响了。
原来殖民者西班牙已经知道了意大利统一运动武装已经到达了西西里岛的消息,他们马上派遣部队前来攻击。
但是,令人可笑的是,正当加里波第他们想要还击的时候,敌人的炮声却突然停了。
原来港口内还有两艘英国商船,他们刚提出抗议,西班牙的士兵们便不敢再进行攻击了。
于是,加里波第的红衫军就很快就以港口为基地,借机又扩大了规模,接着,在实力大增之后,加里波第便下令向西西里岛的首府巴勒莫进军。
但是,当他们刚刚出发在进军的路上,就遇到了一座梯形的高山,山上则有两倍于红衫军的敌人占领。
按道理说,一看这情况,红衫军就应该退缩了。
然而,加里波第的红衫军却并没有退缩。
在经过了一阵猛冲猛打之后,红衫军就占领了这一座高山。
然后,兵临首府巴勒莫。
于是,5月27日的凌晨,天还没有亮,总攻就开始了!在持续了两天两夜的战斗后,西班牙占领军和西西里王国的反动军队是死的死,逃的逃,红衫军取得了胜利。
但是,为了不让敌人有喘息的机会,当年的八月,加里波第就带领着红衫军向着西西里王国的首都那不勒斯进军。
随后,在当地人民的支持下,那不勒斯也获得了解放。
然后,1860年11月初的一天,意大利新国王厄马努埃尔便和意大利统一运动的最高首领加里波第手拉手走在了那不勒斯的大街上,接受全市人民对他们得热烈欢迎。
至此,意大利开始走向了统一之路。
总之,十八世纪的意大利为何能够实现全境统一?来源于意大利人民不屈不挠的战斗意志。
随机文章塞普蒂米乌斯·西弗勒斯拱门简介日本富士山简介详解c5运输机和c17的区别,造价3亿美元的C17性能更优尼古拉特斯拉有多恐怖,击败爱迪生成为现代电气学之父地表喀斯特地貌类型,喀斯特地貌的形成过程(大自然风化而成)
如何在不丢失数据的情况下进行C盘重装系统操作指南
软件支持 在线重装、U盘制作、自定义重装 等多种模式。
简介:重装C盘系统通常是解决电脑各种顽固问题的有效方法。
然而,系统重装过程中的数据丢失风险让许多用户望而却步。
本文将为您提供一个详细的操作指南,帮助您在重装系统时保护重要数据的安全。
工具原料:系统版本:Windows 11品牌型号:Dell XPS 13 9310 或 Apple MacBook Pro 2022软件版本:AOMEI Backupper 6.5 或 Time Machine一、准备工作1、备份重要数据。
无论使用哪种型号的电脑,备份数据是确保数据安全的关键。
对于Windows用户,建议使用AOMEI Backupper这样的第三方工具来创建完整的系统镜像备份。
对于Mac用户,可以使用Time Machine进行全量备份。
2、创建Windows恢复驱动器。
如果您的电脑是Windows系统,建议使用Windows 11自带的工具制作一个恢复驱动器,以备不时之需。
从设置中选择“更新和安全”“恢复”“创建恢复驱动器”,根据提示操作即可。
二、重装系统前的安全考虑1、确保足够的电池电量。
在重装系统之前,确保笔记本电脑有足够的电池电量或者直接连接电源,以避免重装过程中断电导致系统损坏。
2、确认系统激活信息。
在开始重装之前,确保记录当前Windows系统的激活密钥。
如果没有记录,使用工具如Belarc Advisor来提取。
三、进行系统重装1、对于Windows。
在需要重装系统的电脑上插入Windows安装介质(可从微软官网下载并制作USB安装盘)。
引导系统从USB启动后,按提示选择“自定义”安装选项,并选择C盘进行重装。
记得只格式化C盘,其他分区不受影响。
2、对于Mac。
启动Mac时,同时按住Command (?) + R键,进入macOS恢复模式。
选择“重新安装 macOS”,按照指示进行安装即可。
确保不选择“抹掉硬盘”选项,以保存原有数据。
3、数据恢复。
系统重装完成后,利用事先创建的备份恢复数据。
对于Windows用户,可以通过AOMEI Backupper恢复所需文件;对于Mac用户,使用Time Machine进行恢复。
拓展知识:1、云存储的重要性。
除了本地备份,云存储也是一种有效的备份方法。
使用OneDrive、Google Drive或iCloud等云服务来存储重要文件,不仅能提供额外的数据安全保障,还可以在需要时随时随地访问。
2、SSD与数据安全。
随着SSD在新设备中逐渐普及,其稳定性和速度为系统重装提供了更好的体验。
然而,SSD在重复读写后可能出现寿命问题,定期备份显得尤为重要。
总结:重装C盘系统可能听起来复杂,但只要做好充分的准备工作,便可以轻松完成这一任务。
重装系统不仅能解决系统故障,还能提高电脑性能。
然而,无论何时,请将数据备份放在首位,以确保您的信息安全无虞。
标签: 注意:本站所刊载的文章均为学习交流之用,请勿用于商业用途。
对于商业使用,请联系各自版权所有者,否则法律问题自行承担。
Windows7旗舰版密钥激活指南:全面解析与常见问题解决方案 系统之家win7重装全攻略:解决所有安装难题 如何在不丢失数据的情况下进行C盘重装系统操作指南 分类于: 回答于:2024-12-19 简介:重装C盘系统通常是解决电脑各种顽固问题的有效方法。
然而,系统重装过程中的数据丢失风险让许多用户望而却步。
本文将为您提供一个详细的操作指南,帮助您在重装系统时保护重要数据的安全。
工具原料:系统版本:Windows 11品牌型号:Dell XPS 13 9310 或 Apple MacBook Pro 2022软件版本:AOMEI Backupper 6.5 或 Time Machine一、准备工作1、备份重要数据。
无论使用哪种型号的电脑,备份数据是确保数据安全的关键。
对于Windows用户,建议使用AOMEI Backupper这样的第三方工具来创建完整的系统镜像备份。
对于Mac用户,可以使用Time Machine进行全量备份。
2、创建Windows恢复驱动器。
如果您的电脑是Windows系统,建议使用Windows 11自带的工具制作一个恢复驱动器,以备不时之需。
从设置中选择“更新和安全”“恢复”“创建恢复驱动器”,根据提示操作即可。
二、重装系统前的安全考虑1、确保足够的电池电量。
在重装系统之前,确保笔记本电脑有足够的电池电量或者直接连接电源,以避免重装过程中断电导致系统损坏。
2、确认系统激活信息。
在开始重装之前,确保记录当前Windows系统的激活密钥。
如果没有记录,使用工具如Belarc Advisor来提取。
三、进行系统重装1、对于Windows。
在需要重装系统的电脑上插入Windows安装介质(可从微软官网下载并制作USB安装盘)。
引导系统从USB启动后,按提示选择“自定义”安装选项,并选择C盘进行重装。
记得只格式化C盘,其他分区不受影响。
2、对于Mac。
启动Mac时,同时按住Command (?) + R键,进入macOS恢复模式。
选择“重新安装 macOS”,按照指示进行安装即可。
确保不选择“抹掉硬盘”选项,以保存原有数据。
3、数据恢复。
系统重装完成后,利用事先创建的备份恢复数据。
对于Windows用户,可以通过AOMEI Backupper恢复所需文件;对于Mac用户,使用Time Machine进行恢复。
拓展知识:1、云存储的重要性。
除了本地备份,云存储也是一种有效的备份方法。
使用OneDrive、Google Drive或iCloud等云服务来存储重要文件,不仅能提供额外的数据安全保障,还可以在需要时随时随地访问。
2、SSD与数据安全。
随着SSD在新设备中逐渐普及,其稳定性和速度为系统重装提供了更好的体验。
然而,SSD在重复读写后可能出现寿命问题,定期备份显得尤为重要。
总结:重装C盘系统可能听起来复杂,但只要做好充分的准备工作,便可以轻松完成这一任务。
重装系统不仅能解决系统故障,还能提高电脑性能。
然而,无论何时,请将数据备份放在首位,以确保您的信息安全无虞。
菜科网系统致力于解决 Windows 系统重装解决方案,提供高效、安全、免费的系统重装服务。