网络编程之SocketIO基础

继上一篇文章《网络编程之IO与NIO阻塞分析》的讲解,已经知道了网络编程的基本方式,今天将继续进行网络编程相关概念的深入讲解。

1.基本概念

1.1 IO(BIO)

Blocking IO,同步阻塞式IO(传统的网络编程模型),完全依靠网络,具有以下特点:

  • Client/Server模型,两个进程直接进行相互通信,其中服务端提供配置信息(绑定的IP和端口),客户端通过连接操作向服务端监听的地址发送请求,通过三次握手建立连接。连接成功,双方就可以进行通信
  • 采用线程池和任务队列可以实现伪异步的IO通信框架
  • 传统IO缺点:占用资源多,耗时长

1.2 NIO

Non-Blocking IO 同步非阻塞,多了一个管道的概念,以空间换时间的概念。

  • 1.0版本:只实现非阻塞,未实现异步
  • 2.0版本:JDK1.7之后异步非阻塞(AIO)
  • NIO与BIO一个最大的区别就是,NIO中的selector采用了epoll代替了传统的select实现,性能大大提升

1.2 AIO

NIO2.0,异步+非阻塞 (JDK1.7以后实现)

1.3 Socket

套接字,应用程序间的TCP通信通常通过Socket向网络发出请求或者应答网络请求

  • Socket和ServerSocket为java.net包中,ServerSocket用于服务端
  • Socket是在建立网络连接时候用的。在连接成功时,应用程序的两端(客户端和服务端)都会产生一个Socket实例,操作这个实例来完成所需的会话。
  • 对于一个网络连接来说,Socket和ServerSocket是平等的,不管是在服务端还是在客户端,他们的工作都是通过SocketImpl类及其子类完成的。

2.阻塞和非阻塞

程序在等待调用结果(消息,返回值等)时的状态(具体的技术,接收数据的方式、状态),针对网络传输而言。

  • 阻塞:调用结果返回前,当前的线程会被挂起,直到得到结果之后才会返回。(也就是说,应用程序在获取网络数据的时候,如果网络传输数据的时候很慢,那么程序就一直等着,知道传输完毕为止)
  • 非阻塞:在不能立刻得到结果之前,该调用不会阻塞当前线程。(应用程序可以直接获取已经准备就绪好的数据,无需等待)

可参见上一篇文章《网络编程之IO与NIO阻塞分析》的详细讲解。

3.同步和异步

关注的是消息通信机制(synchronous communication/asynchronous communication),一般是面向操作系统与应用程序对IO操作的层面上来区分(server端应用程序的执行方式),针对程序层面而言。

  • 同步:应用程序发出了一个“调用”时,在没有得到结果之前,该“调用”就不会返回。直到调用返回。(应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某个方法上,直到数据准备好了,或者采用轮询的策略检查数据的就绪状态,如果就绪则获取数据)
  • 异步:一个异步过程调用发出之后,调用者不会立即得到结果,而是“被调用者”通过状态、通知等来通知调用者,或者通过回调函数来通知应用程序。(所有的IO读写操作交给操作系统处理,与我们的应用程序没有直接关联,我们的程序不关心IO读写,当操作系统完成了IO读写操作时,会给我们的应用程序发送通知,我们的应用程序直接拿走数据即可)

典型的异步编程模型Node.js

4.Socket的连接过程

Socket的连接过程分为四个步骤:服务器监听、客户端请求服务器、服务器确认、进行通信。

  • 服务器监听:服务器端的套接字并不定位具体的客户端套接字,而是处理等待连接的状态(阻塞),实时监控网络状态
  • 客户端请求:客户端提示网络请求,连接的目标就是服务端的Socket。所以,客户端要连接的Socket必须首先描述出它要连接的服务器的Socket,指出服务器Socket的地址和端口,然后才向服务器提示网络连接的请求
  • 服务端连接确认:服务端套接字监听到客户端的连接请求,就会响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的情况发送给客户端
  • 客户端连接确认:一旦客户端确认了服务端的描述,连接就建立好了。双方就可以开始通信了。并且服务器端的套接字进行处于监听状态,继续监听其他的客户端套接字的请求

5.NIO详解

一般称作Non-Blocking IO,同步非阻塞,在传统的TCP直接建立连接的基础,做了一层抽象,把客户端(SocketChannel)和服务端(ServerSocketChannel )注册到多路复用器上,然后Selector回去轮询所有注册到服务器上的SocketChannel的通道,根据通道的状态(connect/连接、Accept/阻塞、Read/可读、Write/可写)执行相关操作。(概念好理解,编程不好实现)。
这边涉及几个核心概念:Buffer(缓冲区,填充数据的结构)、Channel(管道)、Selector(选择器,多路复用器),如下图所示:

NIO核心概念.png

5.1 Buffer

Buffer是一个包含一些要写入或者读取的数据的对象,在NIO类库中加入Buffer对象,体检了新库与原IO的一个重要的区别:

  • 在面向流的IO中,可以直接将数据写入或者读取到Stream对象中
  • 在NIO库中,所有的数据都用缓冲区处理读写操作
  • 缓冲区本质上是一个数组,通常是一个字节数组(ByteBuffer),为缓冲区提供了数据访问的读写操作,如位置、容量、上限等概念

5.2 Channel

网络数据通过Channel进行读写操作,通道与流不同之处在于,通道是双向的(可以用于读写或者二者同时进行,最关键的可以与Selector结合起来),而流是单方向的(一个流必须是InputStream或者OutputStream的子类)。通道分为两大类

  • 网络读写(SelectableChannel),子类:
    • SocketChannel(客户端)
    • ServerSocketChannel(服务端)
  • 文件操作(FileChannel)

5.3 Selector

NIO编程的基础,核心。提供了已经选择就绪的任务的能力,Selector会不断的轮询注册到其上的Channel,如果某个通道发生了读写操作,这个通道就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以取得就绪的Channel的集合(可能有多个channel),从而进行后续的IO操作

  • 一个Selector理论上可以负责无数个Channel通道,因为JDK使用了epoll代替了传统的select实现,获得的连接句柄没有限制。
  • Selector线程就类似一个管理者,只不过是轮询哪个管道的数据已经准备好,然后通知CPU去读写数据
  • 当Channel注册到Selector后,Selector会分配给Channel一个Key值,Selector是以轮询的方式进行查找注册的Channel,当Channel准备好了,Selector就会识别,通过KEY值找到相应的Channel进行相关的数据处理操作。
  • Selector只负责轮询注册到其上的Channel的状态位,不负责具体操作,轮询出来的SocketChannel一定是准备就绪好的数据(缓冲好的数据,非阻塞状态),而在BIO中是一个字节一个字节的传输(阻塞状态)

NIO编程需要注意的问题:TCP拆包粘包的问题(解码的时候才会出现这个问题)

6.AIO(NIO2.0)

异步非阻塞,在NIO的基础上,引入了异步通道的概念,并提供了异步文件和异步套接字通道的实现,从而在真正意义上实现了异步非阻塞。AIO不需要通过Selector注册Channel进行轮询操作即可实现异步读写,从而简化了NIO编程模型。(概念不好理解,编程好实现

  • AsynchronousSocketChannel
  • AsynchronousServerSocketChannel

7.IO多路复用的系统调用使用epoll代替了select,主要有以下几方面原因(整理自《netty权威指南》):

  • 支持一个进程打开的socket描述符(FD)不受限制(仅受限于操作系统的最大文件句柄数)
  • I/O效率不会随着FD数目的增加而线性下降
  • 使用mmap加速内核与用户空间的消息传递
  • epoll的API更简单
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容