一般传输大的文件和信息的时候需要涉及到分包和组包,方法有很多,下面一种是借鉴了别人的思路,供大家参考哈

分包

  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分包组包的更多相关文章

  1. c#Udp分包组包方法

    udp通信协议,相信大家都知道这个.由于是无连接的协议,所有udp的传输效率比tcp高.但是udp协议传输较大的数据文件得分包 最近写了个分包组包的方法,拿来和大家分享,如果有什么不妥的地方,欢迎点评 ...

  2. c# UDP分包发送

    考虑到UDP的高速和其他协议的复杂性,做了一个依靠时间发送的分包组包重发的UDP库. https://github.com/jinyuttt/UDPTTL.git

  3. Qt通过UDP传图片,实现自定义分包和组包

    一.包头结构体 //包头 struct PackageHeader { //包头大小(sizeof(PackageHeader)) unsigned int uTransPackageHdrSize; ...

  4. Qt Socket 收发图片——图像拆包、组包、粘包处理

    之前给大家分享了一个使用python发图片数据.Qt server接收图片的Demo.之前的Demo用于传输小字节的图片是可以的,但如果是传输大的图片,使用socket无法一次完成发送该怎么办呢?本次 ...

  5. TCP的组包、半包、粘包与分包

    一.概念 1)组包.简单的说就是tcp协议把过大的数据包分成了几个小的包传输,接收方要把同一组的数据包重新组合成一个完整的数据包. 2)半包.指接受方没有接受到一个完整的包,只接受了部分,这种情况主要 ...

  6. TCP 、UDP、IP包的最大长度

    1.概述 首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层. 其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Da ...

  7. TCP,UDP,IP数据包的大小限制

    1.概述 首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层. 其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Da ...

  8. 网络Socket编程UDP协议例子

    服务端代码 public class UDPChatServer { //通讯端口 private Integer port=8000; //数据报文的通讯通道对象 private DatagramC ...

  9. 网络编程 套接字socket TCP UDP

    网络编程与套接字 网络编程 网络编程是什么: ​ 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 ​ 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...

随机推荐

  1. 装饰器模式(Decorator)

    转自http://blog.csdn.net/hust_is_lcd/article/details/7884320 1.认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象 ...

  2. ZBreak

    https://github.com/atskyline/ZBreak 最近用电脑用的多,总觉得有必要2个小时休息一会.就花了一点点时间写了这个小东西如果连续使用电脑超过2个小时会弹出一个窗口提示. ...

  3. jquery的API查看 / prepend、prependTo、append、appendTo的用法

    理解jquery设计思想 记住大部分jquery API的使用 英文:http://api.jquery.com/ 中文: http://www.css88.com/jqapi-1.9/ http:/ ...

  4. WCF:为 SharePoint 2010 Business Connectivity Services 构建 WCF Web 服务(第 1 部分,共 4 部分)

    转:http://msdn.microsoft.com/zh-cn/library/gg318615.aspx 摘要:通过此系列文章(共四部分)了解如何在 Microsoft SharePoint F ...

  5. 使用ServiceStackRedis链接Redis简介

    注:关于如何在windows,linux下配置redis,详见这篇文章:) 目前网上有一些链接Redis的C#客户端工具,这里介绍其中也是目前我们企业版产品中所使用的ServiceStackRedis ...

  6. android中GridView关于间距的属性值介绍

    android:columnWidth  设置列的宽度.关联的方法为:setColumnWidth(int)  stretchMode属性值的作用是设置GridView中的条目以什么缩放模式去填充空间 ...

  7. HDU 1011-Starship Troopers(树形背包)

    题意: 有n个洞,连接像一棵树,每个包含一定数量的怪和价值,给你m个士兵,每个士兵能打20个怪,杀完一个洞的怪可得该洞的价值才可继续打相连的下面的洞(每个士兵只能打一个洞),求获得的最大价值. 分析: ...

  8. 自动脚本工具新版 v2.0

    自动脚本工具 下载 下载工具后,解压,直接双击 "execute.bat" 文件后(前提已配置好 jdk 1.7 的环境),会生成文件夹 "output",该文 ...

  9. C语言基础--结构体对齐,位域,联合体

    结构体对齐 1--结构体对齐的原因与意义 许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值K(通常是2,4,8)的倍数,而这个k则被称为该数据类型的对齐模数 ...

  10. wuzhicms 模块开发

    首先,模块开发需要了解五指cms的目录结构: 然后,我们需要新增加一个模块目录: 再app下面创建 如:content 下面包含文件: 前台文件的创建: 看下 index.php 的内容: <? ...