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
网络编程与套接字 网络编程 网络编程是什么: 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...
随机推荐
- 【转】Cocos2d-x 程序是如何开始运行与结束的
转自:http://blog.leafsoar.com/archives/2013/05-05.html 题记:对于技术,我们大可不必挖得那么深,但一定要具备可以挖得很深的能力 问题的由来 怎么样使用 ...
- Erlang入门(一)
读erlang.org上面的Erlang Course四天教程1.数字类型,需要注意两点1)B#Val表示以B进制存储的数字Val,比如 7> 2#101.5 二进制存储的101就是10进制的5 ...
- Hibernate4.x之Session--常用方法
接上篇文章继续学习Hibernate的Session(http://www.cnblogs.com/dreamfree/p/4111777.html) 持久化对象的状态; 站在持久化的角度,Hiber ...
- SharePoint 2010 获取列表中所有数据(包括文件夹内)的方法
转: http://blog.csdn.net/wangwenism/article/details/8751411 SharePoint的列表能存储文件以及文件夹,用户使用的时候,经常会建几个分类文 ...
- POJ 3630- Phone List(Trie)
题意:给一组串,是否存在一个串是另一个的前缀. 分析:val[N]保存树节点上是否组成一个串 #include <map> #include <set> #include &l ...
- opencv 在工业中的应用:二维标定
在工业中经常要检测一个零件的尺寸,但是图像处理得到的是像素值,怎么才能得到实际的毫米值呢?这就要用到二维标定,我用OPENCV写了一个利用标定板进行标定的DEMO. 很多商业软件都没有二维标定的功能, ...
- leptonica 学习笔记2——pixBackgroundNormSimple
1 pixBackgroundNormSimple 函数功能:自适应背影标准化 位置:adampmap.c /*-------------------------------------------- ...
- ALM11需求类型
- 转载Ajax.Net--ScriptManager和UpdatePanel控件
ScriptManager和UpdatePanel控件联合使用可以实现页面异步局部更新的效果.其中的UpdatePanel就是设置页面中异步局部更新区域,它必须依赖于ScriptManager存在,因 ...
- BAT及各大互联网公司2014前端笔试面试题:HTML/CSS篇
BAT及各大互联网公司2014前端笔试面试题:HTML/CSS篇 2014/08/03 · Web前端, 开发 · CSS, HTML, 技术面试 分享到: 188 MongoDB集群之分片技术应用 ...