前言
这里在前言简单了解一下应用层重点协议: 1.NAT: 把局域网ip转换为公网ip(路由器中的技术) 2.NAPT: 把局域网主机ip+port转换为路由器公网ip+port(路由器中的技术)
一、TCP协议段格式
二、TCP协议的特点
TCP,即Tranamission Control Protocol(传输控制协议),传输层协议 流套接字:使用传输层TCP协议 以下为TCP的特点(细节后续会写到):
- 有连接
- 可靠传输:网络数据传输的方式,是一跳一跳的经过路途中的网络设备,就可能发生数据丢失
- 面向字节流:可以多次的收发数据(连接没有关闭时,可以多次的接收数据,也可以多次的发送数据)
- 有接收缓冲区,也有发送缓冲区:后续学习确认应答机制,超时重传机制,都会使用/依赖这两个缓冲区。缓冲区:发送数据时,是先写到发送缓冲区(write),再刷新缓冲区(flush);接收数据时,也是先由接收缓冲区来保存数据,然后交给程序
- 大小不限:因为可以多次收发,且每次收发都可以很大
- 全双工:每端既可以发,也可以收
可靠传输:不是等于安全传输 所谓的安全,就包含篡改数据的问题 这里的可靠,是可能发生数据丢失,还有机制保证对方能接收到
三、TCP原理
1.可靠传输机制
(1)确认应答机制: 发送的数据报,对方要返回一个确认应答的数据报(类似上网课,要确认某个同学是否在听课,要让他回答一声)
实现的方式: 如果没有确认应答报,引出超时重传机制:
(2)超时重传机制: 发送的数据报,超过一定的时间,还没有收到确认应答的数据报,就需要重新发送(不是程序做的,而是系统在实现tcp协议栈的时候,就实现的功能)(数据还在缓冲区中,系统就可以重发) 这里发送端会基于”32位序号“来重传及去重 去重:数据包没有丢,但网速比较慢,可能多次重传及多次确认应答
超时时间设置多少?(了解) 系统动态地计算:指数倍数增长(超时时间初始值 * 2n ),n累计到一个阈值就关闭连接
(3)连接管理机制: 发送真正的数据之前,要先建立连接 (三次握手)
syn:申请建立连接的标志位 连接:客户端和服务端,都是在自己程序基于tcp的socket保存了一个连接状态(作用:我是否能发送数据到对方)
三次握手:
- 客户端发送syn到服务端,申请建立客户端到服务端的连接
- 服务端返回syn+ack给客户端,这里的ack是第一次syn的应答,及申请建立服务端到客户端的连接
- 客户端接收到第2个数据报,状态就置为established(建立客户端到服务端连接),返回ack回服务端(第二次syn的应答),服务端接收到这个ack,状态就置为established,建立了服务端到客户端连接
不需要再收发数据,就可以关闭连接:四次挥手
fin:申请关闭连接的标志位 服务端先申请关闭连接,或客户端先申请,都是可以的
四次挥手:
- 客户端发送fin数据报到服务端:申请关闭客户端到服务端的连接
- 服务端接收到fin状态置为close_wait;返回一个ack的应答(这个动作是系统实现tcp协议栈默认执行的,不需要程序执行调用代码)
- 服务端发送一个fin数据报到客户端:申请关闭服务端到客户端的连接(程序手动调用socket.close来发送)
为什么设置为手动? 程序可以执行一些关闭连接前的工作:如销毁资源等
- 客户端返回ack回服务端(第三次fin的应答),且状态置为time_wait,此时需要再等待一段时间,再置为closed;服务端接收到这个数据报,状态置为closed关闭连接状态
为什么客户端还需要再等待一段时间? 第四次ack也可能丢包:如果丢包,服务端要重传第三个fin的数据报,此时,客户端就需要进行应答
(4)流量控制: 流量控制:服务端返回的ack数据报中,包含了”16位窗口大小“字段,标识接收端接收缓冲区剩余空间大小,以此来限制发送端的发送速度(根据接收端处理能力,来设置发送数据的大小) 滑动窗口大小,就是发送数据大小,是以流量窗口大小为其中一个依据
(5)拥塞控制: 发送端网络状况不明时,贸然发送大量数据就可能导致大量丢包(一次性发10个集装箱的快递,运输状况不明,就可能拥堵) 采用”慢启动“的机制,先发送少量的数据报探探路,然后再慢慢的增多(先少发一点快递,然后慢慢增多)
2.效率机制
(1)滑动窗口: 如果没有滑动窗口,就只能采取一发一收,再一发一收 这样串行化的传输方式,效率低 滑动窗口: 就是一次性发送多个数据报(类似多线程并发的方式) 窗口大小: 无需等待而可以继续发送的数据报最大值(一次性发送的多个数据报总的大小) 具体设置多大窗口: min(流量窗口大小,拥塞窗口大小) 窗口如何滑动: 接收到的ack下一个是n,就可以滑动到n-1的位置
如果丢包,如何保证可靠传输? 情况一: 情况二: (2)延迟应答 接收到数据后,马上就ack应答,流量窗口大小就比较小;稍微等待一定时间,程序处理一部分接收的数据,就可以把流量窗口设置的更大,这样发送的窗口就可以更大(网络吞吐量更高) 延时是为了更高的吞吐量(效率),但也不能无限延迟
- 数量
- 时间:不能超过超时时间
(3)捎带应答: 服务端接收到客户端发送的消息,要返回ack,及一个响应的消息,不用两次数据发送,二是可以合并为一个数据
四、粘包问题
tcp是面向字节流,可以多次接受和发送;对应用层来说: 到底发送多少次,算一个发送的应用层完整格式的数据,就不知道了 到底接收多少次,算一个接收的应用层完整格式的数据,也不知道了
粘包: 就是包和包之间的边界没有确定好 如何解决: 确定包的边界
- 对于定长的包,保证每次都按固定大小读取即可
- 对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置
- 对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是程序员自己来定的,只要保证分隔符不和正文冲突即可)
|