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
网络编程与套接字 网络编程 网络编程是什么: 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...
随机推荐
- Java [Leetcode 273]Delete Node in a Linked List
题目描述: Write a function to delete a node (except the tail) in a singly linked list, given only access ...
- hdu 2844 Coins
Coins Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepted S ...
- 关于触发器、存储过程和DBlink的综合运用 (转)
关于触发器.存储过程和DBlink的综合运用 需求描述: 需要在两个不同oracl数据库实例中进行数据逻辑处理.如果A实例中的表有新数据插入或者数据更新,那么在B实例中执行与之相关的存储过程. 先假设 ...
- 无状态、REST、RESTful 和 Web Services【整理】
在理解 OpenStack 的过程中,常常遇到 REST 这个概念,现从各处搜罗如下: 对 Web Service 的理解: Web 服务有点像对计算机友好的网页,基于让程序可以跨网络交换信息的标准和 ...
- 傲游浏览器4,傲游浏览器5如何一键批量打开url链接。
傲游浏览器批量打开网址的插件没用了.有很多网友发了方法也无法实现.实际上,是可以实现傲游浏览器4,傲游浏览器5一键批量打开url链接的.我来告诉大家如何来实现.最新的M5都能使用.在收藏夹添加一个收藏 ...
- Install minidwep-gtk
Hi to everyone in this time i'm going to show you how to install minidwep-gtk to test your own wifi ...
- HIbernate学习笔记(二) hibernate对象的三种状态与核心开发接口
1.在hibernate中持久化对象有三个状态,这个面试时可能会问到: (1)transient瞬时态:在数据库中没有与之匹配的数据,一般就是只new出了这个对象,并且在session缓存中也没有即此 ...
- Apache启动是出现the requested operation has failed
出现的原因: 原因一:80端口占用例如IIS,另外就是迅雷. 原因二:软件冲突装了某些软件会使apache无法启动如Dr.com 你打开网络连接->TcpIp属性->高级->WINS ...
- Android下NFC的简单使用
现在很多手机已经配备了NFC(Near Field Communication 近场通信)的功能,我就为此专门研究过,可以到本文末尾下载源代码. Android官方资料:http://develope ...
- AndroidManifest笔记
1.android:configChanges如果配置了这个值,比如"orientation",在屏幕旋转时会调用Activity的onConfigurationChanged,而 ...