Socket之UDP分包组包
一般传输大的文件和信息的时候需要涉及到分包和组包,方法有很多,下面一种是借鉴了别人的思路,供大家参考哈
分包
1、取出需要传输的文件和字符的长度和大小放入缓存区里面;
2、设定固定传输的长度,用需要传输的长度除以固定传输的长度都可以得到需要传输的次数;
3、传输一次字节流中包括(文件名字、文件名字大小、顺序、数据总块数、数据长度、数据总长度)
4、包组装完成后,都剩下发送;当确定到接收方收到后,在传下一次包;
FileStream m = new FileStream(FullName, FileMode.Open, FileAccess.Read); //FullName得到文件完整路径
Byte[] BTmp = new byte[m.Length];
m.Read(BTmp, , Convert.ToInt32(m.Length));
m.Close();
string fileName = dirs[j].FullName.Replace("\\", "/");
while (fileName.IndexOf("/") > -)
{
fileName = fileName.Substring(fileName.IndexOf("/") + );
}
byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName);
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); int m_intMessageLength = BTmp.Length;
int m_intSerial = ;
int m_intBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(m_intMessageLength) / Convert.ToDouble(m_intBlockLength))); //数据分割块数
int m_intlastlength = ;
//求出最后一块数据长度
if (m_intMessageLength % m_intBlockLength == )
m_intlastlength = m_intBlockLength;
else
m_intlastlength = m_intMessageLength - (m_intBlocks - ) * m_intBlockLength; while (m_intSerial < m_intBlocks)
{
try
{
int m_intLength = ; //数据长度
if ((m_intSerial + ) == m_intBlocks)
m_intLength = m_intlastlength;
else
m_intLength = m_intBlockLength; byte[] data = new byte[m_intLength + + fileNameByte.Length];
int place = ;
Buffer.BlockCopy(BitConverter.GetBytes(m_intSerial), , data, place, ); //顺序戳
place += ;
Buffer.BlockCopy(BitConverter.GetBytes(m_intBlocks), , data, place, ); //数据总块数
place += ;
Buffer.BlockCopy(BitConverter.GetBytes(m_intLength), , data, place, ); //数据长度
place += ;
Buffer.BlockCopy(BitConverter.GetBytes(BTmp.Length), , data, place, ); //数据总长度
place += ;
////////////////
Buffer.BlockCopy(fileNameLen, , data, place, ); //文件名长度
place += ;
Buffer.BlockCopy(fileNameByte, , data, place, fileNameByte.Length); //文件名大小
place += fileNameByte.Length;
Array.Copy(BTmp, m_intSerial * , data, place, m_intLength); //复制数据
sersoc.SendTo(data, , data.Length, SocketFlags.None, Remot);
bool result = sersoc.Poll(, SelectMode.SelectRead);
if (result)
{
byte[] linshi = new byte[];
int recv = sersoc.ReceiveFrom(linshi, ref Remot);
int biaoji = BitConverter.ToInt32(linshi, );
int i = BitConverter.ToInt32(linshi, );//i值为111时表示接到客户端的确认
if (biaoji == ) m_intSerial = i;
if (i == ) break;
} } //endtry
catch (System.Exception pe)
{
Console.WriteLine(pe.ToString());
}
组包
1、收到包后,取出数据总长度和文件名字;
2、根据顺序写入字节流中,还原成原始包;
int m_intSerial = ;
int m_intBlocks = ; //数据分割块数
int m_intLength = ; //数据长度
int m_intMessageLength = ;
int place = ;
int recv;
int biaoji = ;
place = ;
m_intSerial = BitConverter.ToInt32(bytesF, place);//顺序戳
place += ;
m_intBlocks = BitConverter.ToInt32(bytesF, place);//数据总块数
place += ;
m_intLength = BitConverter.ToInt32(bytesF, place);//数据长度
place += ;
m_intMessageLength = BitConverter.ToInt32(bytesF, place);//数据总长度
place += ;
int count = BitConverter.ToInt32(bytesF, place);//文件名长度
place += ;
string fileName = Encoding.UTF8.GetString(bytesF, place, count);//文件名
place += count;
if (m_intSerial == )
{ m_intGetCount = ; data = new byte[m_intMessageLength]; } //申明数据的总长 Array.Copy(bytesF, place, data, m_intBlockLength * m_intSerial, m_intLength); //复制数据
Socket之UDP分包组包的更多相关文章
- c#Udp分包组包方法
udp通信协议,相信大家都知道这个.由于是无连接的协议,所有udp的传输效率比tcp高.但是udp协议传输较大的数据文件得分包 最近写了个分包组包的方法,拿来和大家分享,如果有什么不妥的地方,欢迎点评 ...
- c# UDP分包发送
考虑到UDP的高速和其他协议的复杂性,做了一个依靠时间发送的分包组包重发的UDP库. https://github.com/jinyuttt/UDPTTL.git
- Qt通过UDP传图片,实现自定义分包和组包
一.包头结构体 //包头 struct PackageHeader { //包头大小(sizeof(PackageHeader)) unsigned int uTransPackageHdrSize; ...
- Qt Socket 收发图片——图像拆包、组包、粘包处理
之前给大家分享了一个使用python发图片数据.Qt server接收图片的Demo.之前的Demo用于传输小字节的图片是可以的,但如果是传输大的图片,使用socket无法一次完成发送该怎么办呢?本次 ...
- TCP的组包、半包、粘包与分包
一.概念 1)组包.简单的说就是tcp协议把过大的数据包分成了几个小的包传输,接收方要把同一组的数据包重新组合成一个完整的数据包. 2)半包.指接受方没有接受到一个完整的包,只接受了部分,这种情况主要 ...
- TCP 、UDP、IP包的最大长度
1.概述 首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层. 其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Da ...
- TCP,UDP,IP数据包的大小限制
1.概述 首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层. 其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Da ...
- 网络Socket编程UDP协议例子
服务端代码 public class UDPChatServer { //通讯端口 private Integer port=8000; //数据报文的通讯通道对象 private DatagramC ...
- 网络编程 套接字socket TCP UDP
网络编程与套接字 网络编程 网络编程是什么: 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...
随机推荐
- apache开源项目--lume
lume 是一个分布式.可靠和高可用的服务,用于收集.聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型.这是一个可靠.容错的服务.
- (七)学习CSS之filter属性
filter: alpha(opacity=,finishopacity=,style=)??? alpha是来设置透明度的,它的基本属性是filter:alpha(opacity,finishopa ...
- CF GYM 100703G Game of numbers
题意:给n个数,一开始基数为0,用这n个数依次对基数做加法或减法,使基数不超过k且不小于0,输出最远能运算到的数字个数,输出策略. 解法:dp.dp[i][j]表示做完第i个数字的运算后结果为j的可能 ...
- c#保存datagridview中的数据时报错 “动态SQL生成失败。找不到关键信息”
ilovejinglei 原文 C#中保存datagridview中的数据时报错"动态SQL生成失败.找不到关键信息" 问题描述 相关代码 using System; us ...
- Hbase学习笔记(安装和基础知识及操作)
1.Hbase简介 1.面向列的分布式数据库 2. 以HDFS作为文件系统 3. 利用MapReduce处理Hbase中海量数据 4. ZookKeeper作为协调工具 5. sqoop提供Hbase ...
- Proguard使用教程
一.概念 ProGuard是一款免费的Java类文件压缩器.优化器和混淆器.它能发现并删除无用类.字段(field).方法和属性值(attribute).它也能优化字节码并删除无用的指令.最后,它使用 ...
- 那些跟钱有关的事儿 z
这是两段朴实的创业笔记,作者是王信文,2009年南京大学本科毕业,2009年9月到2013年3月在腾讯上海的互动娱乐部门工作,2013年3月到现在和几个前同事一起创立了莉莉丝游戏(手游刀塔传奇是他们后 ...
- 年过三十,我为什么要学习ios 与安卓App 移动端技术
今天跟我华为的同学谈了一些技术/人生方面的感悟,感觉自己的人生目标及后面的工作/生活有了一个比较清晰的认识与规划. 首先我谈了一下我为什么要学习ios与安卓技术,我其实不想通过这二门技术来提升我的薪酬 ...
- oracle触发器学习
转自:http://blog.csdn.net/indexman/article/details/8023740/ 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触 ...
- [原创]git使用入门
创建git项目并初始化 建立一个新文件夹,然后将该文件夹定义为git项目 Lilis-MacBook-Pro:GitDir lili$ mkdir testgit Lilis-MacBook-Pro: ...