SpringBoot + Netty 实现 Json字符串 的传输(一)

怎样把一个Json字符串传输到网络的另一端?

1. 确定传输协议:

    我们在进行网络编程的时候,首先要确定的就是传输协议,常见的传输协议就是UDP和TCP。

    我采用的是TCP,因为,TCP可以保证传输数据的可靠性。

2. 应用层协议。

    为啥应用层还要定义一次协议呢?

    因为,应用层都是面向对象的编程,而传输层面向的是二进制的数据流,所以,我们要定义协议完成数据对象与二进制数据流直接的转换。

    当然,通常来说,传输Json串,有两种方案可以实现:

    A. 以换行符作为分隔符传输Json串,换句话说,就是在每个Json串后面追加一个换行符进行数据传输。这样的话,接收端在接收数据的时候,发现换行符,就意味着一个Json串接收完毕了。

    B. 采用添加包头(或者包头+包尾)的方式传输Json串,包头中可以保存Json串的一些有关传输的信息,包尾可以添加分隔符(可以不添加包尾数据)。

    我们知道,Java语言是要先定义类然后才能创建对应的对象的,如果Json串被接收之后,如果想要反序列化成为Java对象,只有两种方案:一种是使用Map存放Json的属性信息,另一种是自定义Class与Json对应,然后反序列化得到对象。这第二种方案里面,有一个关键的内容是,我们要先知道Json与Class的映射关系才能将Json反序列化成对象,很显然,上面说的A用换行符传输Json串就不适用了,因为,这种方式中,我们无法拿到Json与Class的映射关系(当然,如果Json串里面包含这种关系,是没有什么问题的,我们谈论的思想是想尽量将Json与传输本身分离开来)。

    下面,我们做一下小结:

    方案A传输Json可以将Json映射成Map对象进行数据的访问;

    方案B传输Json可以在包头中定义Class的编号,接收端通过编号找到对应Class类,反序列化成对象进行数据访问。

    我打算使用后者写一个Demo。

3. BIO还是NIO

    BIO虽然编程模型较为简单,但是,这种IO的操作方式,早已淡出了我的视线,IO密集型的程序,BIO会使得大量的线程处于阻塞状态,这对于我这种强迫症患者来讲,是不可容忍的。我的理念里面,多线程的最佳使用场景是运用在CPU密集型的程序当中。所以,为了让一条线程能够管理更多的连接,进行更多的IO操作,我还是选择的NIO(当然,还有一个原因是因为NIO有框架可以简化编程)。

4. 选择框架,毫无疑问,众所周知,SpringBoot + Netty 。

5. 聊一下协议中的数据格式:

头部:4bytes           | 2bytes    | 2bytes    | 2bytes               | 2bytes

          0xFFFE0608 | Version   | Channel | Command         | Length

          开始分隔符    | 协议版本 | 频道号   | 命令字(类ID)| 包体长度

包体:Xbytes

          长度与包头部分定义的长度一致,采用UTF-8编码进行转换

包尾:4bytes

          0xFFFE0806

          结尾分隔符

其中,包尾可以不使用的,我这里添加包尾,是想在接收端遇到碎包时,可以通过包尾分隔符跳过碎包的数据,或者为接收端提供另只用解析报文的方式。这种情况在Demo中并没有进行实现,所以,包尾部分,属于备选信息。

 

 

你可能感兴趣的:(Java,EE)