首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
Windows程序
> 详细
C# SOCKET 粘包、断包处理(一)
时间:
2015-05-12 11:28:10
阅读:
500
评论:
0
收藏:
0
[点我收藏+]
标签:
c#
socket
粘包
断包
一直是用JAVA,关于SOCKET方面,JAVA有一个不错的框架MINA2,对于粘包、断包的处理有这个良好的处理,个人需要写的代码并不太多。
而C#、因为了解不多,也没去看第三方的SOCKET框架,所以只好根据MSDN提示,自己去实现了。
在代码之前,我们先说说处理中会碰到的情况如何:
1、先假设数据包的格式如下:
包长度(4字节)MD5签名(32字节)客户端ID(5字节)数据类型(5字节)数据ID(32字节)数据内容(动态长度、不固定)
|--------------------------------包头78字节--------------------------------------|------包体-----------------|
2、接收数据包时,可能会遇到的问题(假设,每次接收的缓冲区为1024字节):
A、一次就接收到一个完整的包,也即此完整的数据包长度少于1024字节,并且无其他数据包的数据与这个包的数据粘在一起;
也即,此数据包的数据情况如下:
缓冲区:|--------------------------1024字节----------------------|
数据包:|------数据包1------|
B、一个接收的数据中有几个包的数据粘合在一起,也即如下:
缓冲区:|--------------------------1024字节----------------------|
数据包:|------数据包1数据包2数据包3...数据包N------| //N个数据包数据链接在一起,但整体不超过1024个字节
或者数据包:|------数据包1数据包2数据包3.....数据包N(部分数据)-----| //N个数据包数据链接在一起,最后一个包的数据为此数据包的一部分数据
C、一个接收的数据为一个包的部分数据,也即此包的数据长度大于1024个字节,也即如下:
缓冲区:|--------------------------1024字节----------------------|
数据包1:|-------------数据1(某数据包的部分数据)----------------| //某个数据包的部分数据
数据包2:|-------------数据2(某数据包的部分数据)----------------| //某个数据包的部分数据
..........
数据包N:|-------------数据N(某数据包的部分数据)--------| //某个数据包的最后一部分数据,而后面无其他数据包的数据黏在一起
D、一个接收的数据为一个包的部分数据,也即此包的数据长度大于1024个字节,也即如下:
缓冲区:|--------------------------1024字节----------------------|
数据包1:|-------------数据1(某数据包的部分数据)----------------| //某个数据包的部分数据
数据包2:|-------------数据2(某数据包的部分数据)----------------| //某个数据包的部分数据
..........
数据包N:|-------------数据N(某数据包的部分数据)另一个包的数据--| //某个数据包的最后一部分数据,后面有其他数据包的数据黏在一起
3、处理方式:
第一次接收的时候,肯定可以接收到包括描述当前数据包长度的信息,通过解析还原此信息,就可以对比此次数据包的长度与缓冲区的长度,看是属于上述(第二点)的哪一种类型,根据不同的类型,进行相应的处理:
A、类型A,这个情况处理最简单,根据数据包的长度信息,接收并解析数据即可
B、类型B,这种情形得分两个情况处理,不过首先的先得获得缓冲区的数据,然后
1)当N个数据包长度不超过1024字节时:
通过递归,根据每一个包的长度来解析出每一个包的信息就好了
2)当缓冲区的最后一部分数据还有某个包的部分数据时(暂称:数据包X的部分数据A1),那就又得分两种情况处理了:
I、数据包X的部分数据A1的长度大于等于4字节的,也即包括了数据包X的长度信息,并保存这个部分数据A1,并获得数据包X的长度
在下一次接收的时候,需要将刚才保存的数据与这次接收的数据进行粘合,然后在根据之前获得的长度进行处理
II、数据包X的部分数据A1的长度小于4字节的,那就先保存这个部分数据A1
在下一次接收的时候,需要将刚才保存的数据与这次接收的数据进行粘合,并解析出这个包的长度,然后根据这个长度去处理
当然,这I,II两个类型,都可以安装II这个方式处理
C、类型C,这个情况,需要进行记录两个信息,一个是这个数据包的长度,另外一个就是这个包的数据。
1)先获得这个数据包的第一部分数据,保存,然后解析出这个包的长度
2)继续接收数据,并粘合之前保存的数据,直到完成这个数据包所有的数据接收,然后解析这个数据包
D、类型D,这个情况是类型C与类型B的混合体
1)先根据类型C的方式进行数据保存,然后根据这个数据包的长度,来解析数据包
2)然后根据类型B的情况,接收缓冲区最后一部分的数据、也即下一个数据包的部分数据,然后根据类型B的情况进行处理
C# SOCKET 粘包、断包处理(一)
标签:
c#
socket
粘包
断包
原文地址:http://blog.csdn.net/11097082/article/details/45665087
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
动态 WebApi 引擎使用教程(3行代码完成动态 WebApi 构建)
2021-07-28
windows 查看文件的md5/sha1/sha256
2021-07-28
git windows下换行符问题 LF与CRLF转换
2021-07-27
FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。
2021-07-26
K8S--可视化界面Kubernetes Dashboard(API Server方式)
2021-07-26
Redis安装成windows服务
2021-07-26
c#32位支持大内存(>2gb)
2021-07-23
【c#】Dev BarStaticItem问题汇总
2021-07-23
Exception: URL fetch failure on https://s3.amazonaws.com/text-datasets/nietzsche.txt: None -- [WinError 10054] 远程主机强迫关闭了一个现有的连接。
2021-07-22
WinForm使用DataGridView实现类似Excel表格的查找替换
2021-07-22
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!