自定义Udp/Tcp协议/通信协议Socket(进行中)(分包,黏包)

时间:2022-12-15 18:43:22
>自定义Udp/Tcp协议/通信协议(Java/C);自定义构建和解析IM协议消息;IM自定义UDP通信协议 
  C/S的聊天框架源程序,即支持UDP又支持TCP- https://download.csdn.net/download/aaa629690/3701088
 类似于网络通信中的TCPIP协议一般,比较可靠的通信协议往往包含有以下几个组成部分:帧头、地址信息、数据类型、数据长度、数据块、校验码、帧尾。因为在TCP流传输的过程中,可能会出现分包与黏包的现象。我们为了解决这些问题,需要我们自定义通信协议进行封包与解包。

-- Socket的自定义协议设计思路:一般自定义协议会设计好多个字段组成,比如:dataLen+data+type+md5,数据长度+数据+类型+MD5,解析处理就是把这4个字段解析出来,返回byte[4][],便于后续处理。
  网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

  建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

nodeJS实现的socket服务器端Demo,使用protobuf作为数据格式- https://github.com/bobo892589/socket_server_demo

 Socket封装,支持TCP/UDP客户端和服务端,支持自定义粘包处理、验证处理、解析处理- https://github.com/Blankeer/XAndroidSocket
  TCP调试工具SocketTestDlg- http://www.zlmcu.com/document/tcp_debug_tools.html
Android 基于TCP协议的Socket编程(自定义协议)- https://blog.csdn.net/houxuehan/article/details/79296853
基于Java Socket的自定义协议,实现Android与服务器的长连接(二)- https://blog.csdn.net/u010818425/article/details/53448817 -- 一个简单的TCP自定义通信协议- https://www.2cto.com/net/201706/644587.html
产生分包与黏包现象的原因是什么?
 1.产生分包原因:
可能是IP分片传输导致的,也可能是传输过程中丢失部分包导致出现的半包,还有可能就是一个包可能被分成了两次传输,在取数据的时候,先取到了一部分(还可能与接收的缓冲区大小有关系),总之就是一个数据包被分成了多次接收。

 2.产生黏包的原因:
由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器,但是如果发送的网络数据包太小,那么他本身会启用Nagle算法(可配置是否启用)对较小的数据包进行合并(基于此,TCP的网络延迟要UDP的高些)然后再发送(超时或者包大小足够)。那么这样的话,服务器在接收到消息(数据流)的时候就无法区分哪些数据包是客户端自己分开发送的,这样产生了粘包;服务器在接收到数据后,放到缓冲区中,如果消息没有被及时从缓存区取走,下次在取数据的时候可能就会出现一次取出多个数据包的情况,造成粘包现象

 3.什么是封包与解包?
TCP/IP 网络数据以流的方式传输,数据流是由包组成,如何判定接收方收到的包是否是一个完整的包就要在发送时对包进行处理,这就是封包技术,将包处理成包头,包体。
包头是包的开始标记,整个包的大小就是包的结束标。

 4.如何自定义协议?
发送时数据包是由包头+数据 组成的:其中包头内容分为包类型+包长度。
接收时,只需要先保证将数据包的包头读完整,通过收到的数据包包头里的数据长度和数据包类型,判断出我们将要收到一个带有什么样类型的多少长度的数据。然后循环接收直到接收的数据大小等于数据长度停止,此时我们完成接收一个完整数据包。

-- 用帧同步的项目,帧同步方案对网络有着极大的影响,于是采用了RUDP(可靠UDP);TCP提供了过多的保护,在及时性上做了很多的妥协,比如:控制微包(Nagle算法),延时ACK,流量控制,超时重传等,这些设计严重影响了Tcp的速度和及时性。
  首先思考RUDP需要解决哪些问题,然后根据问题加上必要的包头字段:
1. 数据完整性 –> 加上一个16或者32位的CRC验证字段
2. 乱序 –> 加上一个数据包序列号SEQ
3. 丢包 –> 需要确认和重传机制,就是和Tcp类似的Ack机制;在思考一下既然是自定义协议是不是需要一个协议号字段来过滤一些非法包,那么又可以加入一个新字段:
4. 协议字段 –> protol 字段,标识当前使用协议

Java干货之Socket自定义传输协议,可用于一般即时通讯- https://blog.csdn.net/qq_27070443/article/details/62225780
通常IM采取的协议有xmpp、mqtt、protobuf等数据通信私有协议。