分布式通信协议-TCP/IP与常用IO方式

目录

TCP传输过程

 IP 协议和 TCP/UDP 协议

TCP 是如何做到可靠传输的

组播协议 Multicast

IO:BIO与NIO、AIO


网络领域的知识

  1. 协议:tcp、udp、multicast
  2. IO(BIO、NIO、AIO)
  3. Socket
  4. NIO(Netty/Mina)
  5. 序列化和反序列化

TCP传输过程

http请求:

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

http响应:

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

 

 IP 协议和 TCP/UDP 协议

什么是协议

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

什么是IP 协议

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

TCP/IP

TCP 协议能够检测和恢复IP 层提供的主机到主机的通信中可能发生的报文丢失、重复及其他错误。TCP 提供了一个可信赖的字节流通道,这样应用程序就不需要考虑这些问题。同时,TCP 协议是一种面向连接的协议,在使用 TCP 进行通信之前,两个应用程序之间需要建立一个 TCP 连接, 而这个连接又涉及到两台电脑需要完成握手消息的交换

UDP/IP

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

 

TCP 是如何做到可靠传输的

三次握手建立连接、四次挥手关闭连接保证连接的可靠性;滑动窗口协议保证数据传输的可靠性。故TCP协议可以做到传输的可靠。

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 的窗口单位是字节,不是报文段,发送方的发送窗口不能超过接收方给出的接收窗口的数值。

发送窗口

就是发送端允许连续发送的幀的序号表。

发送端可以不等待应答而连续发送的最大幀数称为发送窗口的尺寸。

接收窗口

接收方允许接收的幀的序号表,凡落在 接收窗口内的幀, 接收方都必须处理,落在接收窗口外的幀被丢弃。

接收方每次允许接收的幀数称为接收窗口的尺寸。在线滑动窗口演示功能

https://media.pearsoncmg.com/aw/ecs_kurose_compnetwork_7/cw/content/interactiveanimations/selective-repeat- protocol/index.html

组播协议 Multicast

对于某些信息,多个接受者都可能感兴趣的时候,那么我们应该怎么解决呢?我们可以向每个接受者单播一个数据副本,但是如果这样的话,效率会低;而且同样的数据发送多次,浪费带宽。

解决方案是,我们可以把复制数据包的工作交给网络来做, 而不是由发送者负责。这样无论是多少客户端,都没问题有两种分发类型,广播(broadcast)和多播(multicast); 广播:网络中的所有主机都会接收到一份数据副本

多播:消息只发送给一个多播地址,网络只是将数据分发给哪些想要接收发送到该多播地址的数据的主机。总的来说,要实现这个功能,只有UDP 是最合适的

广播

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

多播

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

 

IO:BIO与NIO、AIO

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。

事件分离器:在IO读写时,把 IO请求 与 读写操作 分离调配进行,需要用到事件分离器。根据处理机制的不同,事件分离器又分为:同步的Reactor和异步的Proactor。

BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程

AIO是发出IO请求后,由操作系统自己去获取IO权限并进行IO操作;NIO则是发出IO请求后,由线程不断尝试获取IO权限,获取到后通知应用程序自己进行IO操作。

先来个例子理解一下概念,以银行取款为例: 

  • 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写);
  • 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API);
  • 阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回);
  • 非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)

Java对BIO、NIO、AIO的支持:

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

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

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

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

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

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

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

猜你喜欢

转载自blog.csdn.net/qq_35909080/article/details/84782784