Java网络编程-Netty
[TOC]
“早熟的人通常都晚熟,骄傲的人又很急性” ——《士兵突击》
理性的人最容易陷入感性的麻烦。该来的早晚要来,逃避只是把该难受的时间延后。随着真相揭开,时间发酵,然后看透当初懦弱丑恶的自己。
自责是无用,规划协调好今后的工作和生活。
最近在忙一个网络编程的项目,其实项目从去年七月就开始忙这个项目了,不过当时一直比较消极,效率很低。看了一堆教学视频,结果啥也没记住。
索性尝试写个博客,看能不能把自己零碎的阅读拼起来。
一、网络编程的基本知识
1)OSI 模型
虽然只是应用,但还是需要了解一下底层的模型。
应用发送消息首先是要将数据推给内核系统的协议栈。
二、套接字模型
套接字编程是面向连接的,故关心两点:ip地址和端口号。
从上图可以看出,socket编程的工作流程:
初始化 ServerSocket 将其bind到ip地址和端口号上,接着开启监听listen,最后阻塞到accept上等待client的连接请求。
client 首先初始化 连接 Socket,接着向server端的地址和端口发起 Connection request. 此时执行TCP的三次握手(UDP用的是DatagramSocket 类。)
连接会话(session)建立,进行一切业务处理操作。
- client向内核发起write的系统调用执行写操作,发送请求,数据从Application被拷贝到内核协议栈。
- 协议栈将字节流通过网络设备传输到server端的内核协议栈。
- server端通过read系统调用, 将协议栈中client 传输的数据, 拷贝到Application,进行解析,并执行业务处理后,以同样的方式写给client 进行响应。
故,一旦连接建立,数据传输是双向的!
client,server关闭连接。
- 当client需要和server断开连接时,调用close函数。此时发生的操作是,系统内核向该连接链路上的server发送一个FIN包,server收到后执行被动关闭,
- 此时client收到server反馈前,认为连接是正常的, 此时整个链路处于半关闭的状态。
- 当server执行被动关闭时,也会调用close函数,此时整个链路才进入全关闭状态, 双方都会感知到连接已关闭。
webSocket地址格式: 通用地址结构(16字节),IPV4地址结构(16字节),IPV6地址结构(28字节),本地地址结构(最多110字节:本地文件无需端口,路径不同地址可变)。
HTTP,WebSocket的区别和联系:HTTP是应用层协议,基于TCP Socket实现,通常是短连接,客户端只能不断轮询从服务端获得消息。WebSocket是对HTTP的增强,利用TCP双向特性,增强服务端到客户端的传输能力,服务端可以直接推送消息到客户端。
编程实例:
File: MyServer.java
1 | import java.io.*; |
File: MyClient.java
1 | import java.io.*; |
三、Netty框架
官网:https://netty.io/wiki/user-guide-for-4.x.html
翻译版:http://ifeve.com/netty5-user-guide/
上面有官网,Netty是一款基于NIO(Nonblocking I/O, 非阻塞IO)的网络通信框架。基本原理推荐这篇文章:
其实本来选择Netty就是为了省些事,因为它封装的功能多。(不过其实真的挺难搞的)
Netty概览:
- Bootstrap类,处理 开始线程,打开sockets等。
- EventLoopGroup,是一组EventGroup,多个EventGroup组合可以共享一些资源,例如线程等。
- EventLoop , 保持不断寻找新事件的loop, 例如:来自网络sockets的输入数据,当一个event发生时,继续进行至适当的 event handler, 例如: ChannelHandler