网络编程之SocketIO基础

作者: landy8530 | 来源:发表于2017-11-04 15:10 被阅读316次

继上一篇文章《网络编程之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更简单

相关文章

  • 网络编程之SocketIO基础

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

  • iOS-Socket网络通信-框架与API

    Socket基础概念 网络中进程之间如何通信? 网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则...

  • 初步接触socketIO服务

    一、配置socketIO服务 配置好服务之后需要启动二、启动socketIO服务 这样socketIO的服务就已经...

  • 1.解释WebSocket,socketio

    1.解释WebSocket,socketio WebSocket:是一个标准网络传输协议 WebSocket协议是...

  • java 网络编程之基础代码

    一、网络编程起步,接触程序image.png 二、开启线程 1、客户端向服务器端发送文本数据1.png 2、服务器...

  • 网络编程之1.简明网络基础

    OSI模型 开放网络互联 主机 应用层:访问网络服务的接口DNS、HTTP 表示层:提供数据格式转换服务URL加密...

  • autojs双向通信

    牙叔教程 简单易学 使用场景 socketIO socketIO SocketIO是在客户端和服务端之间建立的双向...

  • IP网络基础——IP编址

    文章来自公众号:网络工程师笔记 网络层位于数据链路层与传输层之间。网络层中包含了许多协议,其中最为重要的协议就是I...

  • 实时对话消息(netty-socketio使用)

    netty-socketio-first 标签(空格分隔): socket.io netty-socketio j...

  • RabbitMQ基础教程之Spring&JavaConf

    RabbitMQ基础教程之Spring使用篇 相关博文,推荐查看: RabbitMq基础教程之安装与测试 Rabb...

网友评论

    本文标题:网络编程之SocketIO基础

    本文链接:https://www.haomeiwen.com/subject/pobfmxtx.html