JAVA复习之网络—— 传输层TCP/UDP协议

传输层

*负责数据能够从发送端传输到接受段,负责可靠的传输

*端口号是啥?

**
物理意义上的端口,比如,ADSL Modem、集线器、交换机、路由器用于连接其他网络设备的接口,
逻辑意义上的端口,一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。我们这里将要介绍的就是逻辑意义上的端口。

0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.
1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的
**

UDP协议

**

UDP协议段格式
在这里插入图片描述

UDP协议的特点

1 无连接: 在传输之前不需要建立连接,知道IP和端口号就直接传输
2 不可靠:没有应答确认机制和超时重传等机制 ,如果因为网络故障等原因导致该段数据没有传输到服务端,UDP也不会发生任何信息给给应用层。
3 面向数据报:不能够灵活的控制读写数据的次数和数量(应用层给UDP多长的报文UDP就原样发送不会进行拆分)
4 缓冲区:UDP没有发送缓冲区,只有接受缓冲区,如果缓冲区的满了,UDP数据就会被丢弃,且这个缓冲区不能保证接受的顺序和发送的顺序是相同的
5 UDP传输的数据大小是有限的不能超过64K
**

TCP

**

在这里插入图片描述

TCP协议的特点

  1. 有链接的: 一定是「一对一」才能连接,不能像 UDP 协议 可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;
  2. 可靠传输: 无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端
  3. 面向字节流的:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节已经收到,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃
  4. 有接受缓冲区和发送缓冲区
  5. 数据的大小是不限的

为什么需要TCP协议?工作在那一层?
IP 层是「不可靠」的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性。
如果需要保障网络数据包的可靠性,那么就需要由上层(传输层)的 TCP 协议来负责。
因为 TCP 是一个工作在 传输层的 可靠数据传输的服务,它能确保接收端接收的网络包是 无损坏、无间隔、非冗余和按序的。

什么是TCP连接
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
建立一个 TCP 连接是需要客户端与服务器端达成上述三个信息的共识。
Socket :由 IP 地址和端口号组成
序列号 :用来解决乱序问题等
窗口大小 :用来做流量控制

TCP 四元组可以唯一的确定一个连接,四元组包括如下:
源地址
源端口
目的地址
目的端口

TCP是如何保证可靠性的?

  1. 协议头中的校验和 和序列号
  2. 确认应答机制:发送的数据包携带序号,响应的数据包携带确认序号,发送端可以知道哪些数据已经发送了
  3. 超时重传机制:如果客户端在一定的时间内(单次传输的最大时间*2)没有收到服务器发送的确认数据包,就会进行重新发送。TCP为了保证无论在任何环境下都能比较高性能的通信, 因此会动态计算这个最大超时时间
  4. 连接管理机制:正常情况下TCP要经过三次握手建立连接四次挥手断开连接
  5. 流量控制机制:接受段的接受能力有限(如果发送的过快,导致接受段的接受缓存被塞满,就会产生丢包),需要告知发送端发送的数据大小,通过窗口大小字段来设置。因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control)
  6. 拥塞控制:发送端在不清楚网络的情况下不会默然发送大量的数据包,可能会导致网络阻塞,TCP引用了慢启动等机制处理这种情况。

TCP如何保证其效率的?

  1. 滑动窗口机制:并行的方式一次发送多个数据包,可以提高效率。窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认
    应答过的数据, 才能从缓冲区删掉;窗口越大, 则网络的吞吐率就越高;
  2. 捎带应答机制:
  3. 延迟应答机制: 果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小,假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K,在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来,如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M。
  4. 快速重传:

TCP的三次握手和四次挥手
在这里插入图片描述
在这里插入图片描述

三次握手

1 第一次握手:客户端向服务端发送请求报文,请求报文中 SYN 为1,同时选择一个初始序列号 seq = x,服务端从LIsten状态进入SYN_SEND(同步已发送状态) 状态
2 第二次握手:服务器收到请求报文后,如果同意连接,就发送确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,服务器进入了SYN_RCVD(同步收到状态)。
3 第三次握手: 客户端收到确认报文之后,还要向服务端给出确认。确认报文为ACK = 1 ,ack=y+1,自己的序列号seq=x+1,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。

为什么要三次握手不能两次握手或者四次握手
1 三次握手才能阻止重复历史连接初始化
2 三次握手才能同步对方的初始序列号
3 三次握手才能避免浪费资源

为啥不能两次握手?
如果是两次握手,假设有一种情形,客户端发送第一个连接请求因为网络原因阻塞了迟迟没有到达服务端,由于客户端没有收到确认报文,以为服务端没有收到连接请求,所以就发起了第二个连接请求,此时服务端收到第二个连接请求,经过两次握手建立了连接,传输数据,然后关闭连接。此时之前滞留的第一个连接请求发送到了服务端,又会建立连接,导致不必要的错误和资源浪费。
如果是三次握手,就算是第一次失效的请求报文发送过来了,服务端就收到了并且回复了确认报文,但是客户端不会发送确认报文,服务器收不到确认,就知道客户端没有发送请求。

如果是两次握手只有客户端的连接请求得到确认,服务端的连接请求得不到确认。

四次挥手

在这里插入图片描述

  1. 客户端向服务器发送断开连接请求,并且停止发送数据,连接释放报文首部FIN=1,其序列号为seq = u,客户端今如FIN_WAIT1 状态
  2. 服务器收到连接释放报文,发出确认报文,ACK =1 ,ack = u+1;并且带上自己的序列号seq = v,此时服务器进入close_wait 状态,客户端向服务器的方向就释放了这时候处于半关闭状态即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。。
  3. 客户端收到服务器的确认请求之后,客户端进入FIN_wait2状态,等待服务器发送的释放报文。
  4. 服务器将最后的数据发送完了,就想客户端发送释放连接报文 FIN =1,此时服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文之后,发出确认报文,ACK = 1,此时客户端就进入了TIME-WAIT状态,服务器收到确认报文后立即进入CLOSED状态,关闭TCP连接。客户端 必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

为啥客户端还要等个2MSL?
MSL:Maximum Segment Lifetime 指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间,如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
第一 :保证客户端发送的最后一个确认报文能够到达服务器,因为这个报文很有可能会丢失,服务器没有收到这个报文的时候回重新发送断开连接请求,而客户端就能够在这个2MSL时间内收到这个重传报文,并且会重启2MSL计时器。
第二:防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

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

如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
滑动窗口时候如果发生了丢包会怎办
情况一:如果数据包抵达了,ACK被丢失了,这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认;
情况二:数据包就直接丢了.
在这里插入图片描述
当某一段报文段丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 “我想要的是 1001”
一样;
如果发送端主机连续三次收到了同样一个 “1001” 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;
这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已经
收到了, 被放到了接收端操作系统内核的接收缓冲区中;

拥塞控制机制
在这里插入图片描述
当TCP开始启动的时候, 慢启动阈值等于窗口最大值;
在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1
少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;
当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降

当TCP开始传输的时候不知道网络情况不能贸然发送大量数据,TCP引入了慢启动等机制

  1. 慢启动:一开始先发少量的包探测网络拥塞程度,再决定按照多大的速度传输数据;
  2. 拥塞避免:当拥塞窗口达到慢启动的阀值的时候,使用拥塞算法让拥塞窗口缓慢增加,不在指数增加而是加法增加。(没经历一个往返就把窗口加一)
  3. 快重传和块恢复:快速的恢复丢失的数据包

如何理解面向字节流

创建一个TCP的socket, 同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区;
调用write时, 数据会先写入发送缓冲区中;
如果发送的字节数太长, 会被拆分成多个TCP的数据包发出;
如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去;
接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;
然后应用程序可以调用read从接收缓冲区拿数据;
另一方面, TCP的一个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工.
由于缓冲区的存在, TCP程序的读和写不需要一一匹配, 例如:
写100个字节数据时, 可以调用一次write写100个字节, 也可以调用100次write, 每次写一个字节;
读100个字节数据时, 也完全不需要考虑写的时候是怎么写的, 既可以一次read 100个字节, 也可以一次read一个字节, 重复100次

TCP的长连接和短连接
HTTP的长连接和短连接问题实际上就是TCP的长连接和短连接问题

  1. HTTP1.0 默认使用短连接:就是客户端没进行一次HTTP操作就建立一次连接,响应以后任务结束就断开
  2. HTTP1.1默认使用长连接:就是当一个网页打开以后,客户端和服务器之间的用于传输HTTP数据的TCP连接不会关闭,客户端再一次访问这个服务器的时候,会继续使用这一条已经建立的连接,长连接不能永久的保持,他有一个保持时间。
  3. 在使用长连接的时候,会在响应头加入Connection:keep-alive

TCP和UDP的区别?

  1. TCP是面向连接的,UDP是无连接的
  2. TCP是可靠的通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达。UDP尽最大努力交付,即不保证可靠交付
  3. UDP具有较好的实时性,工作效率比TCP高,适用于高速传播,实时性要求高的通信
  4. TCP连接只是点到点的;UDP支持一对多,一对一,多对多的交互通信
  5. TCP对系统资源要求比较多,UDP对系统资源要求较少

UDP如何实现可靠?
如果要用UDP实现可靠的传输,那么就必须解决两个问题:丢包和包的顺序问题;需要再应用层来实现

  1. 给数据包进行编号,按照包的顺序进行接收并且存储
  2. 接收到数据包之后,发送确认信息给发送端,发送端接收到确认信息之后再继续发送下一个包,如果接收端收到的数据包编号不是预期的编号,则要求发送端重新发送;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值