3.网络I/O的工作机制

前言:数据从一台主机(服务端)发送到网络中的另一台主机(客户端)需要经过很多步骤:首先需要有相互沟通的意向。其次要有能够沟通的物理渠道(物理链路):是通过电话,还是直接面对面交流。再次,双方见面时语言要能够交流,而且双方说话步调要一致,明白什么时候该自己说话,什么时候该对方说话(通信协议)。所以下面要讲一下通信协议和如何完成数据传输。  

什么是通信协议:通信协议其实就是一种规则和约定。就是两者想要交流必须要知道那种方式交流,什么时候去交流,交流什么内容,这就是通信协议。

什么是socket:socket就是网络中的一个端口,两个程序想要进行数据交互,至少要有一个socket(端口),http协议可以比作一个轿车,而socket可以比作是轿车的发动机,作用是比较重要的。

什么是SYN:是TCP和IP建立连接的一个握手信号。     当客户端和服务端建立正常的TCP网络连接时,  首先客户端会先向服务端发送一个SYN,  然后服务端会使用SYN+ACK接收这个消息, 然后客户端接收到服务器端的SYN+ACK最后客户端在使用ACK接收响应。

什么是ACK:ACK是一个确认字符,确认发过来的数据接收无误。     可以理解SYN是TCP和IP之间发送消息要使用的,可以理解ACK是TCP和IP之间接收响应要使用的。

什么是FIN: FIN可以说是用来关闭连接的。

什么是IP: IP就是你电脑的IP地址,当你和TCP通信是TCP需要知道通信的IP。

3.1.TCP状态转化  (TCP就是一个面向连接的,基于字节流的传输层通信协议)

先看一下如何建立和关闭一个TCP连接,TCP状态转换图(这个图太难画就不画了,这个图和书上的图意思一样。):

图解:  

  closed(CLOSED):是TCP状态转换的起始点,在连接超时或者连接关闭时会进入此状态。   为什么closed是起始点呢,因为一开始不可能你就处于连接的状态,在没连接的状态或超时状态就是进入closed,等你连接时就会走listen的状态。

  listen(LISTEN):服务端在等待连接时的状态,当服务端调用socket,bind,listen函数,会进入此状态,此状态是被动打开的,也就是客户端连接时进入此状态。

  syn-sent(SYN-SENT):这个状态是由closed主动打开的,当客户端发送syn给服务端,服务端不能正确连接,则直接进入closed状态。

  syn-rcvd(SYN-RCVD):服务端接收客户端的syn请求,服务端由listen状态进入该状态。同时服务端要回应一个ack,发送一个syn给客户端;另一种状态是:客户端在发送syn的同时接收到了服务端的syn请求,客户端会由syn-sent转换到该状态。

  established(ESTABLISHED):服务器端和客户端完成3次握手后进入该状态,说明已经可以传输数据了。

  fin-wait_1(FIN-WAIT_1):主动关闭的一方,由established状态进入此状态。具体动作是发送fin(关闭连接)给对方。

  fin-wait_2(FIN-WAIT_2):主动关闭的一方,接收到对方的fin  ack(关闭连接和响应),进入此状态。由此不能再接收对方的数据,但是能够向对方发送数据。

  close-wait(CLOSE-WAIT):接收到fin以后,被动关闭(被动关闭连接)的一方进入此状态。具体动作是在接收到fin的同时发生ack。

  last-ack(LAST-ACK):被动关闭(被动关闭连接)的一方,发起关闭请求,由close-wait状态进入此状态。具体动作是发生fin给对方,同时在接收到ack时进入closed状态(就是通信结束以后进入无连接的状态。)。

  closing(CLOSING):两边同时发起关闭请求时,会由fin-wait_1进入此状态,具体动作是接收到fin请求,同时响应一个ack。

  time-wait(TIME-WAIT):这个状态比较复杂,但也是我们最常见的一个连接状态,有三个状态可以转化为此状态。

      由fin-wait_2转换到time-wait,具体情况是:在双方不同时发起fin的情况下,主动关闭的一方在完成自身发起的关闭请求后,接收到被动关闭一方的fin后进入此状态。

      由closing转换到time-wait,具体情况是:在双方同时发起关闭,都做了发起fin的请求,同时接收到了fin并做了ack的情况下,这时就由closing状态进入time-wait状态。

      由fin-wait_1转换到time-wait,具体情况是:同时接收到fin(对方发起)和ack(本身发起的fin回应),它与closing转换到time-wait的区别在于本身发起的fin回应的ack先于对方的fin请求到达,而由closing转换到time-wait则是fin先到达。

3.2.影响网络传输的因素

将一份数据从一个地方正确的传输到另一个地方所需要的时间我们称之为响应时间,影响这个响应时间的因素有很多。

  1.网络带宽:带宽和宽带不一样,但是却差不多,这个带宽的速度回影响到响应时间的速度,一般平均网络带宽只有1.7Mb/s左右。

  2.传输距离:传输数据,也就是数据在光纤中要走的距离,光的传播速度很快,但也是有时间的,而且光纤不是直线走的,也有折射率,而且传输也有传输延迟这种问题。

  3.TCP拥塞控制:TCP传输是一个“停-等-停-等”的协议,传输方和接受方的步调要一致,要达到步调一致就要通过拥塞控制来调节。TCP在传输时会设定一个窗口,这个窗口的大小是由带宽和RTT决定的。计算的公式是带宽xRTT。通过这个值可以得出理论上最优的TCP缓冲区的大小。

3.3.Java Socket的工作机制

  socket这个概念没有对应到一个具体的实体,它描述计算机之间完成相互通信的一种抽象功能。打个比方,可以把socket比作两个城市之间的交通工具,有了它,就可以在城市之间来回穿梭了。交通工具有多种,每种交通工具也有相应的交通规则。socket也一样,也有多种。大部分情况下我们使用的都是基于TCP/IP的流套接字,它是一种稳定的通信协议。

socket通信示例图:

主机A的应用程序要能和主机B的应用程序通信,必须通过Socket建立连接,而建立Socket连接必须由底层TCP/IP来建立。建立TCP需要底层IP来寻址网络中的主机。网络层使用的IP可以帮助我们根据IP地质来找到目标主机,但是在一台主机上可能运行着多个程序,如何才能与指定的应用程序通信就要通过TCP或UPD的地址也就是端口号来指定。这样就可以通过一个socket实例来唯一代表一个主机上的应用程序的通信链路了。

3.4.建立通信链路

当客户端要与服务端通信时,客户端首先要创建一个socket实例,操作系统将为这个socket实例分配一个没有被使用的本地端口号,并创建一个包含本地地址、远程地址和端口号的套接字数据结构,这个数据结构将一直保存在系统中知道这个连接关闭。在创建socket实例的构造函数正确返回之前,将要进行TCP的三次握手协议,TCP握手协议完成后,socket实例对象将创建完成,否则将抛出IOException错误。

与之对应的服务端将创建一个serverSocket实例,创建serverSocket比较简单,只要指定的端口号没有被占用,一般实例创建都会成功。同时操作系统也会为serverSocket实例创建一个底层数据结构,在这个数据结构中包含指定监听的端口号和包含监听地址的通配符,通常情况下都是“*”一个星号,即监听所有地址。之后当调用accept()方法时,将进入堵塞状态,等待客户端的请求。当一个新的请求到来时,将为这个连接创建一个新的套接字数据结构,改套接字数据的信息包含的地址和端口信息正是请求源地址和端口。这个新创建的数据结构将会关联到serverSocket实例的一个未完成的连接数据结构列表中。注意,这时服务端的与之对应的socket实例并没有完成创建,而要等到与客户端的3此握手完成后,这个服务端的socket实例才会返回,并将这个socket实例对应的数据结构从未完成列表中移到已完成列表中。所以与serverSocket所关联的列表中每个数据结构都代表与一个客户端建立的TCP连接。

3.5数据传输

传输数据是我们建立连接的主要目的,下面说一下如何通过socket传输数据。

当连接已经建立成功时,服务端和客户端都会拥有一个socket实例,每个socket实例都有一个inputStream和OutPutStream,并通过这两个对象来交互数据,同时我们也知道网络I/O都是以字节流传输的,当创建SOcket对象时,操作系统将会为inputStream和outputStream分别分配一定大小的缓存区,数据的写入和读取都是通过这个缓存区完成的,写入端将数据写到outputStream对应的SendQ队列中,当队列填满时,数据将被转移到另一端InputStream的RecvQ队列中,如果这时RecvQ已经满了,nameOutputStream的write方法将会堵塞,直到RecvQ队列有足够的空间容纳SendQ发送的数据。特别值得注意的是,这个缓存区的大小及写入端的速度和读取端的速度非常影响这个链接的数据传输效率,由于可能会发送阻塞,所以网络I/O与磁盘I/O不同的是数据的写入和读取还要有一个协调的过程,如果在两边同时传送数据可能会产生死锁。

妈耶终于写完了,后面这些理论没做太多的深入,几天后再过一遍。

深入分析Java I/O的工作机制 (三)网络I/O的工作机制 很详细的更多相关文章

  1. 深入分析 Java I/O 的工作机制

    I/O 问题可以说是当今互联网 Web 应用中所面临的主要问题之一,因为当前在这个海量数据时代,数据在网络中随处流动.这个流动的过程中都涉及到 I/O 问题,可以说大部分 Web 应用系统的瓶颈都是 ...

  2. JAVA Coder 的《深入分析Java Web 技术内幕》读书笔记

    本文基于<深入分析Java Web 技术内幕> <深入分析Java Web 技术内幕>,作者是 许令波,电子工业出版社.本文只是记录书本当中的精彩部分,作个人回顾和技术分享,请 ...

  3. 深入分析 Java I/O 的工作机制--转载

    Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...

  4. 第二章 深入分析Java I/O的工作机制(待续)

    Java的I/O类库的基本架构 磁盘I/O工作机制 网络I/O工作机制 NIO的工作方式 I/O调优 设计模式解析之适配器模式 设计模式解析之装饰器模式 适配器模式与装饰器模式的区别

  5. Servlet工作原理解析 《深入分析java web 技术内幕》第九章

    参考关于servblet的相关文章 侧重概况:https://blog.csdn.net/levycc/article/details/50728921 ibm的相关:https://www.ibm. ...

  6. 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制

    第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...

  7. JVM(三):深入分析Java字节码-上

    JVM(三):深入分析Java字节码-上 字节码文章分为上下两篇,上篇也就是本文主要讲述class文件存在的意义,以及其带来的益处.并分析其内在构成之一 ---字节码,而下篇则从指令集方面着手,讲解指 ...

  8. 高级Java工程师必备 ----- 深入分析 Java IO (三)

    概述 Java IO即Java 输入输出系统.不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO( ...

  9. 深入分析Java Web技术内幕(修订版)

    阿里巴巴集团技术丛书 深入分析Java Web技术内幕(修订版)(阿里巴巴集团技术丛书.技术大牛范禹.玉伯.毕玄联合力荐!大型互联网公司开发应用实践!) 许令波 著   ISBN 978-7-121- ...

随机推荐

  1. js处理日期

    /Date(-62135596800000)/ 如何用js转化为日期时间格式 2015-11-20 14:33:20像这样 var a = '/Date(-62135596800000)/' Date ...

  2. 归并排序之python

    想更好的了解归并排序, 需先了解, 将两个有序列表, 组成一个有序列表 有两个列表  l1 = [1, 3, 5, 7] l2 = [2, 4, 6] 需要将 l1 和 l2 组成一个 有序大列表   ...

  3. python 常忘代码查询 和autohotkey补括号脚本和一些笔记和面试常见问题

    笔试一些注意点: --,23点43 今天做的京东笔试题目: 编程题目一定要先写变量取None的情况.今天就是因为没有写这个边界条件所以程序一直不对.以后要注意!!!!!!!!!!!!!!!!!!!!! ...

  4. Windows和Frames之间的切换

    一些web应用程序有许多Frames或多个Windows. WebDriver支持使用“switchTo”的方法实现的窗口之间切换. driver.switchTo().window("wi ...

  5. AX_CreateAndPostPurch

    static void CreateAndPostPurch(Args _args) { List il = new List(Types::Record); DocumentNum Document ...

  6. VSCode 绿色版(zip压缩包) 添加右键菜单 使用VSCode 打开文件或文件夹

    微软官方下载VSCode 可以下载exe安装外还可以下载zip 压缩包 下载地址: https://code.visualstudio.com/Download 但是zip压缩包却没有了 右键使用VS ...

  7. 小程序跳转tabbar页面

    如果在app.json 配置tabbar 的时候配置了 跳转的页面的链接: 在其余的子页面,设置用navigator 进行跳转会发现 在tabbar 设置过的页面无法进行跳转,这时需要在navigat ...

  8. 给div"上"滑动条

    最近做项目时修改一个遗留的bug,大概是这样:有一个聊天窗口,用户聊天内容展现在窗口上.其实这个窗口是一个带滑动条的div,随着聊天内容的添加,滑动条也越来越长了,这不是重点,重点是每次刷新窗口时候, ...

  9. 01 C语言程序设计--01 C语言基础--第3章 基本数据类型01

    01.1.3.1序言 00:02:17 01.1.3.2 C语言中的基本元素和常量的概念 00:08:54 01.1.3.3示例--常量 00:12:08 01.1.3.4变量的概念和命名规则 00: ...

  10. easyui属性赋值

    了解easyui tree组件的童鞋估计都知道tree的node有他自己单独的属性(id,text,iconCls,checked,state,attribute,target).而原先这个几个属性想 ...