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
网络编程与套接字 网络编程 网络编程是什么: 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...
随机推荐
- 【CSS】
12个很少被人知道的CSS事实 通过CSS禁止Chrome自动为输入框添加橘黄色边框http://www.solagirl.net/override-chromes-automatic-border- ...
- 文件上传利器JQuery上传插件Uploadify
在做日常项目中,经常在后台需要上传图片等资源文件,之前使用过几次这个组件,感觉非常好用 ,但是每次使用的时候都是需要经过一番查阅,所以还不如记住在这里,以后使用的时候就翻翻. 他的官方网站如下:htt ...
- pattern目录
pattern目录 1.创建型模式 JDK1.5枚举Singleton 单例模式 AbstractFactory 工厂方法模式 简单工厂模式 Builder Prototype 2.结构 ...
- Codeforces 629C Famil Door and Brackets DP
题意:给你一个由括号组成的字符串,长度为m,现在希望获得一个长度为n(全由括号组成)的字符串,0<=n-m<=2000 这个长度为n的字符串要求有两个性质:1:就是任意前缀,左括号数量大于 ...
- C# 发送邮件整理,包括控制台程序、WPF、WebForm 及 ASP.NET MVC
一直想把发送邮件的功能掌握,总是各种情况拖着了,这两天终于看了一下,整理一下,希望能帮到想学的. 发送邮件使用SMTP服务器,有两种方案,一种是使用IIS的SMTP功能:另一种是直接使用邮件供应商的S ...
- NOIP2008 双栈队列
1. 双栈排序 (twostack.pas/c/cpp) Tom 最近在研究一个有趣的排序问题.如图所示,通过 2 个栈 S1 和 S2,Tom 希望借助 以下 4 种操作实现将输入序列升序 ...
- Clean Code – Chapter 2: Meaningful Names
Use Intention-Revealing Names The name should tell you why it exists, what it does, and how it is us ...
- STL(pair map set vector priority_queue) poj 3297
POJ 3297 算法竞赛初级杂烩包 题意:学生选课,没个学生只能选一门课.大写字符是课的名字,小写是人名.如果课程后面有多个相同名字算一个,如果一个人选多门课,则他选不上课,输出课和每门课选课人数 ...
- codeforce 609A - USB Flash Drives
排序水题 #include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm&g ...
- javascript设计模式8
桥接模式(将抽象与其实现隔离开来,以便二者独立变化) function sendInfo(element){ var id=element.id; ajax("GET"," ...