TCP_IP协议(传输层)笔记

Posted 一位懒得写博客的小学生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP_IP协议(传输层)笔记相关的知识,希望对你有一定的参考价值。

TCP/IP
应用层:程序员写代码的一层。HTTP、SSH、FTP、DNS
传输层:为了保证两端能够顺利的通讯。TCP、UDP
网络层:用来确定路线和路由选择。
数据链路层:相邻节点的数据接收和转换。

TCP两个对象(客户端和服务器端)
服务器:ServerSocket
客户端:Socket new Socket(IP,Port)

TCP读写数据的重要对象
读:BufferedReader socket.getInputStream 读取readLine()
写:BufferedWriter writer(“内容\\n”)

TCP 与 UDP 的区别
UDP无连接;TCP是有连接的
UDP不稳定;TCP稳定
UDP面向数据报;TCP面向数据流
UDP只有接收缓存区,没有发送缓存区;TCP两个缓存区都有
UDP 和 TCP 使用场景不同,如果对稳定性要求比较高,应该使用TCP;如果对消息丢失不敏感,要求性能比较高,可以考虑使用UDP。




TCP_IP

传输层

最大端口号:0-65535(2^16)

端口号分类
知名端口号:0-1023.。FTP:21;SSH:22;Telent:23;HTTP:80;HTTPS:443;mysql:3306;Tomcat:8080
动态端口号:1024-65535

UDP协议

16位UDP长度 = UDP头部长度(8个字节) + 数据长度
UDP一个包的最大理论长度 = 2^16
16位源端口号:发送程序
16位目的端口号:找到接收程序
校验和:用来确定数据在传输过程中是否被篡改,用来判断数据的正确性。

如果UDP编程的时候数据大小大于64KB会怎样?
1.在应用层进行数据包的拆分和组合。
2.大于64KB不处理,交给TCP/IP协议取处理,它会在网络层进行分包和组包。

全双工与半双工
全:发送端或者是接收端,既能发送消息又能接收消息。
半:发送端只能发送消息,不能接收消息;接收端只能接收消息,不能发送消息。

基于UDP的应用层协议

  • NFS: 网络文件系统
  • TFTP: 简单文件传输协议
  • DHCP: 动态主机配置协议
  • BOOTP: 启动协议(用于无盘设备启动)
  • DNS: 域名解析协议

TCP 协议

4位首部长度
URG:0/1 表示是否为紧急指针。
ACK:是否确认应答消息
PSH:是否立即从缓冲区取走数据
RST:复位标识
SYN:同步序列号标识(TCP连接时候使用)
FIN :结束序列号标识 (TCP断开连接的时候)

TCP 8大特性

确认应答(ACK)

保障TCP稳定的核心机制

问题
发送消息丢失了
ACK丢失了

超时重发

Linux: 500ms

策略
发送不会以固定的频率发送,采用悲观策略,如果第一次失败,大概率第二次也会失败,TCP会以指数级超时时间增长的频率来发送消息。
如果经历了一定的重试次数,消息还没有得到应答,就会停止发送。

连接管理

3次握手 : 为了验证收、发两端的收、发能力。
4次挥手:为了确保发送端和接收端能够正常关闭。

服务端状态
[CLOSED -> LISTEN] :服务器端调用listen后进入LISTEN状态, 等待客户端连接;
[LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文;
[SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行读写数据了;
[ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器返回确认报文段并进入CLOSE_WAIT;
[CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN);
[LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接;
客户端状态
[CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
[SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
[ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入FIN_WAIT_1;
[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
[TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的
时间, 才会进入CLOSED状态.

TIME_WAIT 2 MSL(最大超时时间)

2 MSL = ACK 最大超时时间(1 MSL) + 对方发送给它消息的一个最大等待时间(1 MSL)。
如果程序中存在大量的CLOSE_WAIT 说明程序中存在BUG,没有调用close()主动关闭连接。


滑动窗口


窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 上图的窗口大小就是4000
个字节(四个段);
发送前四个段的时候, 不需要等待任何ACK, 直接发送;
收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据; 依次类推;
操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应搭,只有确认应答过的数据,才能从缓冲区删掉;
窗口越大, 则网络的吞吐率就越高;

情况一:数据包已经抵达,ACK被丢了

ACK = 6001的含义:并不是告诉主机A,已经成功收到5001~6000,而是告诉主机A,我成功接收了 0~6000.
ACK 返回的值是当前(主机B)接收缓冲区的下一个值(最大连续值)

情况二:数据包就直接丢了


当某一段报文段丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 “我想要
的是 1001” 一样;
如果发送端主机连续三次收到了同样一个 “1001” 这样的应答, 就会将对应的数据 1001 -
2000 重新发送;
这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实
之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中;
这种机制被称为 “高速重发控制”(也叫 “快重传”)

流量控制

以结果(接收缓冲区的大小)为导向进行数据的传递。
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应。因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制。

  • 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK端通知发
    送端;
  • 窗口大小字段越大, 说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;
  • 发送端接受到这个窗口之后, 就会减慢自己的发送速度;
  • 如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个
    窗口探测数据段, 使接收端把窗口大小告诉发送端

拥塞控制

网络更新当前时间的网络来动态调整收发的频率就叫拥塞控制。
TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;

  • 此处引入一个概念程为拥塞窗口;

  • 发送开始的时候, 定义拥塞窗口大小为1;

  • 每次收到一个ACK应答, 拥塞窗口加1;

  • 每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口;

  • 为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍

  • 此处引入一个叫做慢启动的阈值

  • 当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长

  • 当TCP开始启动的时候, 慢启动阈值等于窗口最大值;

  • 在每次超时重发的时候,慢启动阈值会变成原来的一半, 同时拥塞窗口置回1;

  • 少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;

  • 当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;

  • 拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.

延迟应答

  • 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;
  • 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
  • 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
  • 如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是
    1M;
策略
每隔一段时间(固定时间)延迟应答一次;
每隔N次(>=2)延迟应答一次;

一定程度加速发送消息的速度。
延迟应答(200MS)的时间一定小于超时重传的时间(500MS)。
窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;

捎带应答

针对对于延时应答的性能优化。

TCP沾包问题

TCP 异常情况

  • 可挽救:电脑重启或者进程结束的时候,它会发送 FIN 请求,和正常关闭TCP是没有什么区别的;
  • 不可挽救:电脑掉电/网线中断:TCP 报活定时器,会定时检测对方是否在线,如果检测的结果是没有任何响应,说明已经掉线,直接释放连接。

小结

  • 稳定性:确认应答;超时重传;连接管理;流量控制;拥塞控制。
  • 保证性能:滑动窗口;延时应答;捎带应答。
  • 基于TCP应用层协议:HTTP;SSH;Telent;FTP:SMTP。

以上是关于TCP_IP协议(传输层)笔记的主要内容,如果未能解决你的问题,请参考以下文章

【网络协议笔记】第四层:传输层(Transport)TCP协议简介(1)

12_tcp_ip相关概念

第二十节 tcp_ip协议

计算机网络_传输层_基本概念

传输层:UDP协议

传输层:UDP 协议