分布式架构(基础篇)——TCP/IP通讯协议V.1.0.1

网络领域的知识 

  • 协议:tcp、udp、multicast 。 IO(BIO、NIO、AIO) 序列化和反序列化【网络通讯中传递对象】

组播(Multicast)传输:在发送者和每一接收者之间实现点对多点网络连接。如果一台发送者同时给多个接收者传输相同的数据,也只需复制一份相同的数据包。它提高了数据传送效率,减少了骨干网络出现拥塞的可能性。】

Java对BIO、NIO、AIO的支持:

  • Java BIO (blocking I/O): 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

  • Java NIO (non-blocking I/O): 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

  • Java AIO(NIO.2) (Asynchronous I/O) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,

BIO、NIO、AIO适用场景分析:

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

  • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

两种网络模型

OSI七层网络模型 【应用层,表示层,会话层,传输层,网络层,数据链路层,物理层】

TCP/IP四层概念模型 【应用层,传输层,网络层,数据链路层】

一个 http 请求,在整个网络中的请求过程当应用程序用 T C P 传送数据时,数据被送入协议栈中,然后逐个通过每一层直到被当作一串比特流送入网络。其中每一层对收到的数据都要增加一些首部信息

比特流BitTorrent)是一种内容分发协议

当目的主机收到一个以太网数据帧时,数据就开始从协议栈中由底向上升,同时去掉各层协议加上的报文首部。每层协议盒都要去检查报文首部中的协议标识,以确定接收数据的上层协议。这个过程称作分用

分用(Demultiplexing)是指将经复用所形成的合成信号恢复为多个原独立信号,或恢复为由这些独立信号所组成的信号群的处理过程。

IP头 包含目的IP地址 和源IP地址   IP协议是一个尽力而为的协议  传输过程中可能会有报文丢失的情况 报文顺序无序 或者重复发送  所以IP协议层之上提供了两种可选协议 TCP 和 UDP 【建立在IP协议层之上】 可以根据应用场景的需求选择

TCP头 携带目标端口号 【对应进程端口号】

 为什么有了 MAC 层还要走 IP 层呢?
mac 地址就好像个人的身份证号,人的身份证号和人户口所在的城市,出生的日期有关,但是和人所在的位置没有关系,人是会移动的,知道一个人的身份证号,并不能找到它这个人,mac 地址类似,它是和设备的生产者,批次,日期之类的关联起来,知道一个设备的 mac,并不能在网络中将数据发送给它,除非它和发送方的在同一个网络内。所以要实现机器之间的通信,还需要有 ip 地址的概念,ip 地址表达的是当前机器在网络中的位置,类似于城市名+道路号+门牌号的概念。通过 ip 层的寻址,我们能知道按何种路径在全世界任意两台 Internet 上的的机器间传输数据。


IP 协议和 TCP/UDP 协议

什么 是 协议
协议相当于两个需要通过网络通信的程序达成的一种约定,它规定了报文的交换方式和包含的意义。比如(HTTP)为了解决在服务器之间传递超文本对象的问题,这些超文本对象在服务器中创建和存储,并由 Web 浏览器进行可视化,完成用户对远程内容的感知和体验

什么 是  IP  协议
T C P 和 U D P 是两种最为著名的传输层协议,他们都是使用 I P 作为网络层协议。IP 协议提供了一组数据报文服务,每组分组报文都是由网络独立处理和分发,就像寄送快递包裹一样,为了实现这个功能,每个 IP 报文必须包含一个目的地址的字段;就像我们寄送快递都需要写明收件人信息,但是和我们寄送快递一样,也可能会出现包裹丢失问题,所以 IP 协议只是一个“尽力而为”的协议,在网络传输过程中,可能会发生报文丢失、报文顺序打乱,重复发送的情况。IP 协议层之上的传输层,提供了两种可以选择的协议,TCP、UPD。这两种协议都是建立在 IP 层所提供的服务基础上,根据应用程序的不同需求选择不同方式的传输;
TCP /IP 和 UDP/IP

TCP协议的主要功能是完成对数据报的确认、流量控制和网络拥塞;自动检测数据报,并提供错误重发的功能;将多条路径传送的数据报按照原来的顺序进行排列,并对重复数据进行择取;控制超时重发,自动调整超时值;提供自动恢复丢失数据的功能。同时,TCP 协议是一种面向连接的协议,在使用 TCP进行通信之前,两个应用程序之间需要建立一个 TCP 连接,而这个连接又涉及到两台电脑需要完成握手消息的交换。

UDP 协议不会对 IP 层产生的错误进行修复,而是简单的扩展了 IP 协议“尽力而为”的数据报文服务,使他能够在应用程序之间工作,而不是在主机之间工作,因此使用 UDP协议必须要考虑到报文丢失,顺序混乱的问题


TCP 是如何做到可靠传输的?

建立 可靠 的 链接
由于 TCP 协议是一种可信的传输协议,所以在传输之前,需要通过三次握手建立一个连接,所谓的三次握手,就是在建立 TCP 链接时,需要客户端和服务端总共发送 3个包来确认连接的建立

TCP  四次 挥手 协议
四次挥手表示 TCP 断开连接的时候,需要客户端和服务端总共发送 4 个包以确认连接的断开;客户端或服务器均可
主动发起挥手动作(因为 TCP 是一个全双工协议),在socket 编程中,任何一方执行 close() 操作即可产生挥手操作。

为什么连接的时候是三次握手,关闭的时候却是四次握手?
三次握手是因为因为当 Server 端收到 Client 端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当 Server 端收到 FIN 报文时,很可能并不会立即关闭 SOCKET(因为可能还有消息没处理完),所以只能先回复一个 ACK 报文,告诉 Client 端,"你发的 FIN 报文我收到了"。只有等到我 Server 端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四步握手。

 

数据 传输 过程 的 流量 控制 和 确认 机制
建立可靠连接以后,就开始进行数据传输了。在通信过程中,最重要的是数据包,也就是协议传输的数据。如果数据的传送与接收过程当中出现收方来不及接收的情况,这时就需要对发方进行控制以免数据丢失。利用滑动窗口机制可以很方便的在 TCP 连接上实现对发送方的流量控制。TCP 的窗口单位是字节,不是报文段,发送方的发送窗口不能超过接收方给出的接收窗口的数值。
滑动窗口协议
滑动窗口(Sliding window)是一种流量控制技术。早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包,谁也发不了数据,所以就有了滑动窗口机制来解决此问题;发送和接受方都会维护一个数据帧的序列,这个序列被称作窗口

简单解释下,发送和接受方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接受方确定,目的在于控制发送速度,以免接受方的缓存不够大,而导致溢出,同时控制流量也可以避免网络拥塞。下面图中的4,5,6 号数据帧已经被发送出去,但是未收到关联的ACK,7,8,9 帧则是等待发送。可以看出发送端的窗口大小为 6,这是由接受端告知的。此时如果发送端收到 4 号ACK,则窗口的左边缘向右收缩,窗口的右边缘则向右扩展,此时窗口就向前“滑动了”,即数据帧 10 也可以被发送。

发送窗口
就是发送端允许连续发送的幀的序号表。发送端可以不等待应答而连续发送的最大幀数称为发送窗口的尺寸。

接收窗口
接收方允许接收的幀的序号表,凡落在 接收窗口内的幀,接收方都必须处理,落在接收窗口外的幀被丢弃。接收方每次允许接收的幀数称为接收窗口的尺寸。在线滑动窗口演示功能


应用层是如何使用 tcp/udp 进行通信的
基于 socket 和 DatagramSocket 进行通信


通信的性能问题?
正常的通信过程如下(BIO) 

我们发现 TCP 响应服务器一次只能处理一个客户端请求,当一个客户端向一个已经被其他客户端占用的服务器发送连接请求时,虽然在连接建立后可以向服务端发送数据,但是在服务端处理完之前的请求之前,却不会对新的客户端做出响应,这种类型的服务器称为“迭代服务器”。迭代服务器是按照顺序处理客户端请求,也就是服务端必须要处理完前一个请求才能对下一个客户端的请求进行响应。但是在实际应用中,我们不能接收这样的处理方式。所以我们需要一种方法可以独立处理每一个连接,并且他们之间不会相互干扰。而 Java 提供的多线程技术刚好满足这个需求,这个机制使得服务器能够方便处理多个客户端的请求。

如何 提高 性能
TCP 协议的通信过程对于 TCP 通信来说,每个 TCP Socket 的内核中都有一个发送缓冲区和一个接收缓冲区,TCP 的全双工的工作模式及 TCP 的滑动窗口就是依赖于这两个独立的 Buffer 和该Buffer 的填充状态。接收缓冲区把数据缓存到内核,若应用进程一直没有调用Socket 的 read 方法进行读取,那么该数据会一直被缓存在接收缓冲区内。不管进程是否读取 Socket,对端发来的数据都会经过内核接收并缓存到 Socket 的内核接收缓冲区。read 所要做的工作,就是把内核接收缓冲区中的数据复制到应用层用户的 Buffer 里。进程调用 Socket 的 send 发送数据的时候,一般情况下是将数据从应用层用户的 Buffer 里复制到 Socket 的内核发送缓冲区,然后 send 就会在上层返回。换句话说,send 返回时,数据不一定会被发送到对端。

Socket 的接收缓冲区被 TCP 用来缓存网络上收到的数据,一直保存到应用进程读走为止。如果应用进程一直没有读取,那么 Buffer 满了以后,出现的情况是:通知对端 TCP协议中的窗口关闭,保证 TCP 接收缓冲区不会移除,保证了 TCP 是可靠传输的。如果对方无视窗口大小发出了超过窗口大小的数据,那么接收方会把这些数据丢弃。


如何使用非阻塞提高性能?
非阻塞要解决的就是 I/O 线程与 Socket 解耦的问题,因此,它引入了事件机制来达到解耦的目的。我们可以认为NIO 底层中存在一个 I/O 调度线程,它不断的扫描每个Socket 的缓冲区,当发现写入缓冲区为空的时候,它会产生一个 Socket 可写事件,此时程序就可以把数据写入到 Socket 中。如果一次写不完,就等待下一次的可写事件通知;反之,当发现缓冲区里有数据的时候,它会产生一个 Socket 可读事件,程序收到这个通知事件就可以从Socket 读取数据了。

关于  NIO
实际上基于上面讲的传统的 BIO 模型,一个请求一个线程的方式,如果要涉及到上千个客户端访问时,会产生很多的问题,比如扩展性、系统资源开销等等。所以我们需要一种方法来轮询一组客户端,来查找哪个连接需要提供服务,这个就是我们讲的“NIO”;
缓冲区
在 NIO 中,所有数据都是用缓冲区处理,在读取数据的时候,它是直接读到缓冲区中,在写如数据的时候,也是写到缓冲区。任何时候访问 NIO 中的数据,都是通过缓冲区进行的操作
通道
Channel 通道,就像一个自来水管一样,可以通过它读取和写入数据,Channel 是全双工的,所以数据是双向流动。

多路复用
多路复用器 Selector,是 NIO 的基础,多路复用器提供选择已经就绪的任务的能力,简单来说,Selector 会不断轮询注册上的 Channel,如果某个 Channel 上面有新的 TCP连接接入、读、写事件,这个 Channel 就处于就绪状态,会被 Selector 轮询出来,然后通过 SelectionKey 可以获取就绪的 Channel 进行 I/O 操作;一个多路复用器可以同时轮询多个 Channel。通过这个机制可以接入成千上万的客户端。

组播协议 Multicast
对于某些信息,多个接受者都可能感兴趣的时候,那么我们应该怎么解决呢?我们可以向每个接受者单播一个数据副本,但是如果这样的话,效率会低;而且同样的数据发送多次,浪费带宽。解决方案是,我们可以把复制数据包的工作交给网络来做,而不是由发送者负责。这样无论是多少客户端,都没问题有两种分发类型,广播(broadcast)和多播(multicast);
广播:网络中的所有主机都会接收到一份数据副本
多播:消息只发送给一个多播地址,网络只是将数据分发
给哪些想要接收发送到该多播地址的数据的主机。总的来说,要实现这个功能,只有 UDP 是最合适的


广播
广播是主机向子网内所有主机发送消息,子网内所有主机都能收到来自某台主机的广播信息,属于点对所有点的通信。广播意味着网络向子网每一个主机都投递一份数据包,不论这些主机是否乐意接收该数据包;

多 播
多播是主机向一组主机发送信息,存在于某个组的所有主机都可以接收到消息,属于点对多点的通信。


1.网络编程时的同步、异步、阻塞、非阻塞?

同步:函数调用在没得到结果之前,没有调用结果,不返回任何结果。
异步:函数调用在没得到结果之前,没有调用结果,返回状态信息。
阻塞:函数调用在没得到结果之前,当前线程挂起。得到结果后才返回。
非阻塞:函数调用在没得到结果之前,当前线程不会挂起,立即返回结果。

Java BIO (blocking I/O): 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

Java NIO (non-blocking I/O): 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

Java AIO(NIO.2) (Asynchronous I/O) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,

BIO、NIO、AIO适用场景分析:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

2.Java如何实现无阻塞方式的Socket编程?

NIO有效解决了多线程服务器存在的线程开销问题。

在NIO中使用多线程主要目的不是为了应对每个客户端请求而分配独立的服务线程,

而是通过多线程充分利用多个CPU的处理能力和处理中的等待时间,达到提高服务能力的目的。

3.什么是java 的序列化(串行化)?

简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),

并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

4.什么情况下需要序列化?序列化的注意事项,如何实现java 序列化(串行化)?

· 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;

· 当你想用套接字在网络上传送对象的时候;

· 当你想通过RMI传输对象的时候;

序列化注意事项

1、如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。

2、静态变量不会被序列化,那是类的“菜”,不是对象的。串行化保存的是对象的状态,即非静态的属性,即实例变量。不能保存类变量。

3、transient关键字修饰变量可以限制序列化。对于不需要或不应该保存的属性,应加上transient修饰符。要串行化的对象的类必须是公开的(public)。

4、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID是否一致,就是 private static final long serialVersionUID = 1L。

5、Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。

6、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象。

5.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

JDK提供的流继承了四大类:

InputStream(字节输入流),OutputStream(字节输出流),Reader(字符输入流),Writer(字符输出流)。

按流向分类:

输入流: 程序可以从中读取数据的流。
输出流: 程序能向其中写入数据的流。

按数据传输单位分类:

字节流:以字节(8位二进制)为单位进行处理。主要用于读写诸如图像或声音的二进制数据。
字符流:以字符(16位二进制)为单位进行处理。
都是通过字节流的方式实现的。字符流是对字节流进行了封装,方便操作。在最底层,所有的输入输出都是字节形式的。
后缀是Stream是字节流,而后缀是Reader,Writer是字符流。

按功能分类:

节点流:从特定的地方读写的流类,如磁盘或者一块内存区域。
过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或者输出流连接创建的。

6.用JAVA SOCKET 编程,读服务器几个 字符,再写入本地显示。

客户端向服务器端发送连接请求后,就被动地等待服务器的响应。

典型的TCP客户端要经过下面三步操作:

1、创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接;
2、通过套接字的I/O流与服务端通信;
3、使用Socket类的close方法关闭连接。

 

服务端的工作是建立一个通信终端,并被动地等待客户端的连接。

典型的TCP服务端执行如下两步操作:

1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;
2、重复执行:
1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;
2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;
3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。

7.TCP/IP在连接时有几次握手?释放时有几次握手?

TCP三次握手连接的建立过程:

 

TCP四次挥手的释放过程:

8.GET 和 POST 区别

查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:/test/demo_form.asp?name1=value1&name2=value2

GET 请求可被缓存

GET 请求保留在浏览器历史记录中

GET 请求可被收藏为书签

GET 请求不应在处理敏感数据时使用

GET 请求有长度限制

GET 请求只应当用于取回数据

POST 方法,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:POST /test/demo_form.asp HTTP/1.1Host: w3schools.comname1=value1&name2=value2

POST 请求不会被缓存

POST 请求不会保留在浏览器历史记录中

POST 不能被收藏为书签

POST 请求对数据长度没有要求

9.dns使用的协议

既使用TCP又使用UDP

首先了解一下TCP与UDP传送字节的长度限制:
UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。当DNS查询超过512字节时,协议的TC标志出现删除标志,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。
区域传送时使用TCP,主要有一下两点考虑:
辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。
TCP是一种可靠的连接,保证了数据的准确性。
域名解析时使用UDP协议:
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向DNS服务器查询的时候使用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。

10.幂等

一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数.

11.Cookies和session区别

Cookies是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术。Cookies是当你浏览某网站时,由Web服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。session: 当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。cookie机制:采用的是在客户端保持状态的方案,而session机制采用的是在服务端保持状态的方案。同时我们看到由于服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助cookie机制来达到保存标识的目的。

Session是服务器用来跟踪用户的一种手段,每个Session都有一个唯一标识:session ID。当服务器创建了Session时,给客户端发送的响应报文包含了Set-cookie字段,其中有一个名为sid的键值对,这个键值Session ID。客户端收到后就把Cookie保存浏览器,并且之后发送的请求报表都包含SessionID。HTTP就是通过Session和Cookie这两个发送一起合作来实现跟踪用户状态,Session用于服务端,Cookie用于客户端

TCP粘包和拆包产生的原因

应用程序写入数据的字节大小大于套接字发送缓冲区的大小
进行MSS大小的TCP分段。MSS是最大报文段长度的缩写。MSS是TCP报文段中的数据字段的最大长度。数据字段加上TCP首部才等于整个的TCP报文段。所以MSS并不是TCP报文段的最大长度,而是:MSS=TCP报文段长度-TCP首部长度
以太网的payload大于MTU进行IP分片。MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。如果IP层有一个数据包要传,而且数据的长度比链路层的MTU大,那么IP层就会进行分片,把数据包分成托干片,让每一片都不超过MTU。注意,IP分片可以发生在原始发送端主机上,也可以发生在中间路由器上。
TCP粘包和拆包的解决策略

消息定长。例如100字节。
在包尾部增加回车或者空格符等特殊字符进行分割,典型的如FTP协议
将消息分为消息头和消息尾。
其它复杂的协议,如RTMP协议等。

三次握手

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据

四次挥手

客户端先发送FIN,进入FIN_WAIT1状态
服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态
服务端发送FIN,进入LAST_ACK状态
客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态
TIME_WAIT的状态就是主动断开的一方(这里是客户端),发送完最后一次ACK之后进入的状态。并且持续时间还挺长的。客户端TIME_WAIT持续2倍MSL时长,在linux体系中大概是60s,转换成CLOSE状态

TIME_WAIT

TIME_WAIT 是主动关闭链接时形成的,等待2MSL时间,约4分钟。主要是防止最后一个ACK丢失。 由于TIME_WAIT 的时间会非常长,因此server端应尽量减少主动关闭连接

CLOSE_WAIT

CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。

为什么需要 TIME_WAIT 状态?

假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 临重发最终ACK的情形。

为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?

如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。

TIME_WAIT 和CLOSE_WAIT状态socket过多

如果服务器出了异常,百分之八九十都是下面两种情况:

1.服务器保持了大量TIME_WAIT状态

2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。

一次完整的HTTP请求过程

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户

长连接

一、基于http协议的长连接
在HTTP1.0和HTTP1.1协议中都有对长连接的支持。其中HTTP1.0需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持.
http1.0请求与服务端的交互过程:
客户端发出带有包含一个header:”Connection: keep-alive“的请求
服务端接收到这个请求后,根据http1.0和”Connection: keep-alive“判断出这是一个长连接,就会在response的header中也增加”Connection: keep-alive“,同是不会关闭已建立的tcp连接.
客户端收到服务端的response后,发现其中包含”Connection: keep-alive“,就认为是一个长连接,不关闭这个连接。并用该连接再发送request.转到a)
二、发心跳包。每隔几秒就发一个数据包过去
TCP如何保证可靠传输?

三次握手。
将数据截断为合理的长度。应用数据被分割成 TCP 认为最适合发送的数据块(按字节编号,合理分片)
超时重发。当 TCP 发出一个段后,它启动一个定时器,如果不能及时收到一个确认就重发
对于收到的请求,给出确认响应
校验出包有错,丢弃报文段,不给出响应
对失序数据进行重新排序,然后才交给应用层
对于重复数据 , 能够丢弃重复数据
流量控制。TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。
拥塞控制。当网络拥塞时,减少数据的发送。
详细介绍http

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

特点

简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

支持B/S及C/S模式。

请求消息Request

请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息从第二行起为请求头部,HOST将指出请求的目的地.User-Agent,服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础.该信息由你的浏览器来定义,并且在每个请求中自动发送等等
空行,请求头部后面的空行是必须的
请求数据也叫主体,可以添加任意的其他数据。
响应消息Response

状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。
消息报头,用来说明客户端要使用的一些附加信息
空行,消息报头后面的空行是必须的
响应正文,服务器返回给客户端的文本信息。
状态码

200 OK //客户端请求成功
301 Moved Permanently //永久重定向,使用域名跳转
302 Found // 临时重定向,未登陆的用户访问用户中心重定向到登录页面
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
http的方法

get:客户端向服务端发起请求,获得资源。请求获得URL处所在的资源。
post:向服务端提交新的请求字段。请求URL的资源后添加新的数据。
head:请求获取URL资源的响应报告,即获得URL资源的头部
patch:请求局部修改URL所在资源的数据项
put:请求修改URL所在资源的数据元素。
delete:请求删除url资源的数据
URI和URL的区别

URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的

URI一般由三部组成:

访问资源的命名机制
存放资源的主机名
资源自身的名称,由路径表示,着重强调于资源。
URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。

URL一般由三部组成:

协议(或称为服务方式)
存有该资源的主机IP地址(有时也包括端口号)
主机资源的具体地址。如目录和文件名等
HTTPS和HTTP的区别

https协议需要到CA申请证书,一般免费证书很少,需要交费。
http是超文本传输协议,信息是明文传输;https 则是具有安全性的ssl加密传输协 议。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
http默认使用80端口,https默认使用443端口
https是如何保证数据传输的安全

https实际就是在TCP层与http层之间加入了SSL/TLS来为上层的安全保驾护航,主要用到对称加密、非对称加密、证书,等技术进行客户端与服务器的数据加密传输,最终达到保证整个通信的安全性。

SSL/TLS协议作用:
认证用户和服务器,确保数据发送到正确的客户机和服务器;
加密数据以防止数据中途被窃取;
维护数据的完整性,确保数据在传输过程中不被改变。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值