1
参考
《网络是怎样连接的》 《计算机网络》 http://www.cyc2018.xyz
https://bithachi.blog.csdn.net/article/details/104722679
运输层概述
运输层术语
- 进程:指计算机中正在运行的程序实体
- 应用进程互相通信:一台主机的进程和另一台主机中的一个进程交换
数据的过程(另外注意通信真正的端点不是主机而是主机中的进程,也
就是说端到端的通信是应用进程之间的通信) - 传输层的复用与分用:复用指发送方不同的进程都可以通过统一个运
输层协议传送数据。分用指接收方的运输层在剥去报文的首部后能把这些
数据正确的交付到目的应用进程 - TCP:传输控制协议
- UDP:用户数据报协议
- 端口:端口的目的是为了确认对方机器是那个进程在于自己进行交互
,比如 MSN 和 QQ 的端口不同,如果没有端口就可能出现 QQ 进程和
MSN 交互错误。端口又称协议端口号,作用是对TCP/IP体系的应用进程
进行统一的标志,使运行不同操作系统的计算机的应用进程能够互相通
信,大小是16位 - 停止等待协议:指发送方每发送完一个分组就停止发送,等待对方确
认,在收到确认之后在发送下一个分组 - 流量控制:就是让发送方的发送速率不要太快,既要让接收方来得及
接收,也不要使网络发生拥塞 - 拥塞控制 :防止过多的数据注入到网络中,这样可以使网络中的路由
器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受
现有的网络负荷 - TPDU 两个对等运输实体在通信时传送的数据单元叫运输协议数据
单元TPDU,根据具体协议称为TCP报文段或UDP用户数据报 - 全局同步 路由器尾部丢弃TCP连接相关的报文段,使很多TCP连接
在同一时间突然进入慢开始状态
网络层和运输层的区别?
- 运输层提供应用进程之间的逻辑通信,也就是说,运输层之间的通信
并不是真正在两个运输层之间直接传输数据。运输层向应用层屏蔽了下面
网络的细节(如网络拓补,所采用的路由选择协议等),它使应用进程
之间看起来好像两个运输层实体之间有一条端到端的逻辑通信信道 - 网络层为主机提供逻辑通信,而运输层为应用进程之间提供端到端的
逻辑通信 - IP数据报的检验和只检验IP数据报的首部,当UDP的检验和是把首部
和数据一起检验
网络层的复用和分用
- 网络层的复用是指发送方不同协议的数据都可以封装成IP数据报发送
出去 - 网络层的分用是指接收方的网络层在剥去首部后把数据交付给相应的
协议
套接字
TCP 用主机的IP 地址加上主机上的端口号作为TCP连接的端点。这样的
端点就叫做套接字(socket)或插口。套接字用(IP 地址:端口号)
来表示。每一条TCP连接唯一被通信两端的两个端点所确定
socket有哪些含义?
- 应用编程接口API 称为socket API,简称为socket
- socket API 中使用的一个函数名也叫作socket
- 调用socket 函数的端点称为socket
- 调用socket 函数时其返回值称为socket 描述符,可简称为socket
- 在操作系统内核中连网协议的Berkeley 实现,称为socket 实现
UDP
应用进程也可以在不影响应用的实时性的前提下,增加一些提高可靠性的
措施,如采用前向纠错或重传已丢失的报文
- UDP无须建立连接,不会引入建立连接的时延
- 无连接状态
- 分组首部开销小,TCP有20B的首部开销,而UDP仅有8B的开销
- 没有拥塞控制,应用层能更好地控制要发送的数据和发送时间,因此
网络中的拥塞不会影响主机的发送效率 - 支持一对一、一对多、多对一和多对多的交互通信
- 面向报文,发送方UDP对应用层交下来的报文,在添加首部后就向下
交付给IP层 - 提供尽最大努力的交付,但这并不意味着应用对数据的要求是不可靠
的,因此所有维护传输可靠性的工作需要用户在应用层来完成
HTTP为什么使用TCP?
HTTP使用TCP而非UDP,是因为对于基于文本数据的Web网页来说,可靠性是
至关重要的
TCP
- 面向连接 应用程序使用TCP协议之前先建立TCP连接,传送数据完毕后
释放连接 - 每一条TCP 连接只能是一对一的
- 提供可靠交付 TCP传送的数据无差错、不丢失、不重复并且按序到达
- 提供全双工通信
- 面向字节流
TCP和UDP的区别?
- 用户数据报协议UDP 是无连接的,尽最大可能交付,没有拥塞控制,面
向报文(对于应用程序传下来的报文不合并也不拆分,只是添加UDP首部)
,支持一对一、一对多、多对一和多对多的交互通信 - 传输控制协议TCP 是面向连接的,提供可靠交付,有流量控制,拥塞控
制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,
把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的
(一对一) - TCP报文段是根据对方给出的窗口值和当前网络拥塞的程度决定大小的,
UDP用户数据报的大小是应用进程给出的
UPD相对TCP优点和缺点?
- TCP优点 TCP的优点是可靠
- TCP缺点 只能支持一对一的数据交互,占用的系统资源也高,有Dos攻击
- UDP优点 快速,可以支持一对一,一对多,多对多的数据交互,UDP被攻
击者利用的漏洞少 - UDP缺点 不可靠,不稳定,数据容易丢失
TCP首部格式
首部长度是20+4n,MSS最大报文段长度(数据字段),默认是536字节
- 源端口和目的端口字段 各占2B。端口是运输层与应用层的服务接口,
运输层的复用和分用功能都要通过端口实现 - 序号字段 占4B。TCP是面向字节流的(即TCP传送时是逐个字节传送的
),所以TCP连接传送的数据流中的每个字节都编上一个序号。序号字段的
值指的是本报文段所发送的数据的第一个字节的序号 - 确认号字段 占4B。是期望收到对方的下一个报文段的数据的第一个字
节的序号。若确认号为N,则表明到序号N-1为止的所有数据都已正确收到 - 数据偏移(即首部长度) 占4位。表示首部长度,它指出TCP报文段的数
据起始处距离TCP报文段的起始处有多远。“数据偏移”单位是32位(以4B为
计算单位)。因此当此字段的值为15时,达到TCP首部的最大长度60B - 紧急位URG URG=1时,表明紧急指针字段有效。它告诉系统报文段中有
紧急数据,应尽快传送(相当于高优先级的数据)。但URG需要和紧急指针
配套使用,即数据从第一个字节到紧急指针所指字节就是紧急数据,比如
中断命令 - 确认位ACK 只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无
效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置1 - 推送位PSH 接收TCP收到PSH=1的报文段,就尽快地交付给接收应用进
程而不再等到整个缓存都填满后再向上交付 - 复位RST RST=1时,表明TCP连接中出现严重差错(如主机崩溃或其他
原因),必须释放连接,然后再重新建立运输连接 - 同步位SYN 同步SYN=1表示这是一个连接请求或连接接收报文。当SYN=1
, ACK=0时,表明这是一个连接请求报文,对方若同意建立连接,则在响应
报文中使用SYN=1,ACK=1。即SYN=1表示这是一个连接请求或连接接收报文 - 终止位FIN 用来释放一个连接。FIN= 1表明此报文段的发送方的数据
已发送完毕,并要求释放传输连接 - 窗口字段 占2B。它指出现在允许对方发送的数据量,接收方的数据缓
存空间是有限的,因此用窗口值作为接收方让发送方设置其发送窗口的依
据,单位为字节。例如,假设确认号是701,窗口字段是1000。这表明,
从701号算起,发送此报文段的接收方方还有接收1000B数据的接收缓
存空间 - 校验和 占2B。校验和字段检验的范围包括首部和数据两部分
- 紧急指针字段 占16位,指出在本报文段中紧急数据共有多少字节(紧
急数据放在本报文段数据的最前面),指向紧急数据的末尾位置
各种应用
- 名字转换 DNS UDP 53
- 文件传送 TFTP UDP 69
- 路由选择协议 RIP UDP
- IP地址配置 DHCP UDP
- 网络管理 SNMP UDP 161/162
- 远程文件服务器 NFS UDP
- IP电话 专用协议 UDP
- 流式多媒体通信 专用协议 UDP
- 多播 IGMP UDP
- 电子邮件 SMTP TCP 25
- 远程终端输入 TELNET TCP 23
- 万维网 HTTP TCP 80
- 文件传送 FTP TCP 21
三次握手
TCP连接的建立采用客户服务器方式,主动发起 TCP 连接建立的应用进程叫
做客户,而被动等待连接建立的应用进程叫做服务器。TCP 连接采用三报文
握手机制。服务器要确认用户的连接请求,然后客户要对服务器的确认进行
确认。
首先客户端与服务器都是处于CLOSED状态,接下来服务端创建传输控制块TCB
,准备接收客户进程的连接请求,这时服务器就进入LISTEN收听状态
- 第一次握手:客户端发送第一个包,其中SYN标志位为1, ACK=0,发送顺
序号seq=X(随机)。客户端进入SYN发送状态,等待服务器确认。这是一个连接
请求报文,客户端进入SYN-SENT(同步已发送)状态 - 第二次握手:服务器收到这个包后发送第二个包,其中包SYN、ACK标志位
为1,发送顺序号seq=y(随机),确认号ack=x+1,这是一个连接接收报文,
服务端进入SYN-RCVD(同步收到)状态 - 第三次握手:客户端收到服务器传来的包后,向服务器发送第三个包,
SYN=0,ACK=1,接收确认号ack=y+1,发送顺序号seq=x+1。此包发送完
毕,客户端ESTABLISHED(已建立连接)状态,服务端收到这个包后也
进入已建立连接状态
注意前两个报文不能携带数据,但是要消耗一个序号,第三个报文可以携带
数据,但是如果不携带数据就不消耗序号,在这种情况下下一个数据报文段
的序号seq=x+1。
- 服务器端的资源是在完成第二次握手时分配的
- 而客户端的资源是在完成第三次握手时分配的,这就使得服务器易于受到
SYN洪泛攻击
SYN攻击
- SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者
就不对其进行再确认,那这个TCP 连接就处于挂起状态,也就是所谓的半连
接状态,服务器收不到再确认的话,还会重复发送ACK 给攻击者。这样更加
会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP 连接,由
于每一个都没法完成三次握手,所以在服务器上,这些TCP 连接会因为挂
起状态而消耗CPU 和内存,最后服务器可能死机,就无法为正常用户提供
服务了,又称为DDoS攻击 - 直接攻击 攻击者用他们自己的没有经过伪装的IP地址快速地发送SYN数
据包,这种攻击非常容易抵御,用一个简单的防火墙规则阻止带有攻击者IP
地址的数据包就可以了 - 欺骗式攻击 攻击者还必须能够用有效的IP和TCP报文头去替换和重新生
成原始IP报文
怎么防范SYN攻击?
- 过滤网关防护 过滤网关主要指明防火墙,当然路由器也能成为过滤网
关。防火墙部署在不同网络之间,防范外来非法攻击和防止保密信息外泄
,它处于客户端和服务器之间,利用它来防护SYN攻击能起到很好的效果
。过滤网关防护主要包括超时设置,SYN网关和SYN代理三种 - 加固tcp/ip协议栈 防范SYN攻击的另一项主要技术是调整tcp/ip协
议栈,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN
cookies技术、增加最大半连接和缩短超时时间等 - 降低SYN timeout时间,使得主机尽快释放半连接的占用
- 采用SYN cookies设置,如果短时间内连续收到某个IP的重复SYN请求
,则认为受到了该IP的攻击,丢弃来自该IP的后续请求报文
接收端为什么要传回SYN?
接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就
是你所发送的信号了。
SYN 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正
常的 TCP 网络连接时,客户机首先发出一个SYN消息,服务器使用SYN-ACK
应答表示接收到了这个消息,最后客户机再以ACK(Acknowledgement[汉译
:确认字符,在数据通信传输中,接收站发给发送站的一种传输控制字符。
它表示确认发来的数据已经接受无误。 ])消息响应。这样在客户机和服务
器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递
传了SYN,为啥还要传ACK?
双方通信无误必须是两者互相发送信息都无误。传了SYN,证明发送方到接
收方的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进
行验证
第三次握手失败了怎么办?
当第三次握手失败时,服务器并不会重传ack报文,而是直接发送RST报文段
,进入CLOSED状态。RST=1就表明TCP连接出现严重错误,此时必须释放连接
,这样做的目的是为了防止SYN洪泛攻击
为什么挥手要四次,而握手只要三次?
建立连接时,ACK和SYN可以放在一个报文里来发送。而关闭连接时,被动关闭
方可能还需要发送一些数据后,再发送FIN报文表示同意现在可以关闭连接了
,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的
wait_time状态是哪个阶段?
通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态。客
户端主动关闭连接时,会发送最后一个ack后,然后会进入TIME_WAIT状态
,再停留2个MSL时间,进入CLOSED状态
timewait一定只能在客户端吗?
客户端和服务端都有可能
怎么优化timewait过多?
- 对于一个处理大量短连接的服务器,如果由服务器主动关闭客户端的连接
,将导致服务器存在大量的处于TIME_WAIT状态的socket,严重影响服务器
的处理能力,甚至耗尽可用的socket
- 高并发可以让服务器在短时间范围内同时占用大量端口
- 短连接表示“业务处理+传输数据的时间远远小于TIMEWAIT超时的时间”
的连接
- 修改短连接为长连接方式
- 修改TIME_WAIT连接状态的上限值,超过此数量时,系统会立即清理出多
余的TIME_WAIT连接 - 开启重用机制 许将TIME-WAIT sockets重新用于新的TCP连接,重用
TIME_WAIT的条件是收到最后一个包后超过1s
timewait需要等待多少?
2MSL。MSL叫做最长报文段寿命,经过2MSL时间,就可以使本连接持续的时间所
产生的所有报文段都从网络中消失
四次握手
服务端发送给客户端的报文段可以拆分为两个报文段。可以先发送一个确认
报文段(ACK=1 ack=x+1),然后再发送一个同步报文段(SYN=1 seq=y)
为什么要三次握手而不是两次?
注意为什么A最后还要发送一次确认,这是为了防止已失效的连接请求报文段
突然又传送到了B。假定A发出的第一个连接请求没有丢失而是因为延迟到了B
,这本是一个早已失效的报文段,但是B在接收到这个报文段后误认为是A又
发出的一个新的连接请求,于是向A发送确认请求建立连接,但是目前的A并
没有打算发送连接请求,所以不会理睬B的确认,当B认为这个连接已经建立
所以会一直等待A发来数据,B的很多资源白白浪费,而且容易被恶意攻击
ACK超时会怎么样?
- 重新传送报文 发送一个数据之后,就开启一个定时器,若是在这个时间
内没有收到刚才发送数据的ACK确认报文(是通过确认序号的方式进行确认
,即刚才发送数据的序列号+1),则对该报文进行重传。如果一直失败,
满一定次数后就会放弃并发送一个复位信号 - 这个定时器的时间(RTO)相当关键,关系着网络资源是否被有效利用,
如果RTO设置过小,部分报文可能遇到网络拥堵或者延迟比较大的情形,这
样就会频繁重传,浪费带宽。如果RTO设置过大的话,发送端需要等待过长
时间才能发现数据丢失,影响网络的传输效率 - 当发送TCP收到窗口大小为0的确认时,就启动坚持计时器。当坚持计时
器期限到时,发送TCP就发送一个特殊的报文段,叫做探测报文 - 保活计时器使用在某些实现中,用来防止在两个TCP之间的连接出现长时
间的空闲,每当服务器收到客户的信息,就将计时器复位。通常设置为两小
时。若服务器过了两小时还没有收到客户的信息,他就发送探测报文段。若
发送了10个探测报文段(每一个75秒)还没有响应,就假定客户除了故障
,因而就终止了该连接
四次挥手
TCP 的连接释放采用四报文握手机制。任何一方都可以在数据传送结束后发
出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再
发送时,则发送连接释放通知,对方确认后就完全关闭了TCP 连接
- 第一次挥手:主动关闭方发送第一个包,其中FIN标志位为1,发送顺序号
seq为u,这个序号值就是前面已经发送的数据的最后一个字节的序号加1,这
是一个连接释放报文,进入FIN-WAIT-1(终止状态1)状态 - 第二次挥手:被动关闭方收到FIN包后发送第二个包,其中发送顺序号seq
为v,确认号ack为u+1,这时接收方就进入CLOSE-WAIT(关闭等待)状态,
这时TCP连接处于半关闭状态,发送方已经没有数据要发送了,接收方还可
以发送数据,发送方收到确认后进入FIN-WAIT-2(终止状态2)状态,等
待接收方发送连接释放报文 - 第三次挥手:发送连接释放报文,其中FIN标志位为1,发送顺序号seq为w
,接收顺序号ack为u+1,此时接收方进入LAST-ACK(最后确认)状态 - 第四次挥手:发送确认报文段,ACK置为1,发送序号是u+1,确认号是w+1
,发送方进入TIME-WAIT(时间等待)状态,这时TCP 连接还没有释放掉,必
须经过时间等待计时器设置的时间2MSL后,发送方才会进入CLOSED 状态,
MSL叫做最长报文段寿命
为什么TIME_WAIT状态需要经过2MSL
- 为了保证A发送的最后一个报文段能够到达B,这个报文段可能丢失,如
果处在LAST-ACK状态的B收不到已发送的FIN+ACK报文段的确认就会超时重
传这个报文段,A在2MSL时间内能收到这个重传的报文段那么A就重传一次
确认,重新启动2MSL计时,最后A和B都能进入CLOSED状态 - 关闭链接一段时间后可能会在相同的IP地址和端口建立新的连接,为了
防止旧连接的重复分组在新连接已经终止后再现。2MSL足以让所有分组都
消失
TCP可靠传输
- 校验、序号、超时和重传保证TCP可靠传输
- 可靠传输机制是为了使数据可以正确稳定的传输和接收而制定的规则
- 校验和 发送的数据包的二进制相加然后取反,目的是检测数据在传输过
程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确
认收到此报文段 - 确认应答+序列号 接收方收到报文就会确认(累积确认:对所有按序接收
的数据的确认)TCP给发送的每一个包进行编号,接收方对数据包进行排序,
把有序数据传送给应用层 - 超时重传 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到
这个报文段。如果不能及时收到一个确认,将重发这个报文段 - ARQ协议 也是为了实现可靠传输的,它的基本原理就是每发完一个分组
就停止发送,等待对方确认。在收到确认后再发下一个分组
停止等待ARQ协议
停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组
就停止发送,等待对方确认。在收到确认后再发下一个分组,停止等待协
议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发
送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组
需要设置一个超时计时器,其重转时间应比数据在分组传输的平均往
返时间更长一些。这种自动重传方式常称为自动重传请求 ARQ,通过
确认和重传机制就可以在不可靠的传输网络上实现可靠的通信
连续ARQ协议
为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用
流水线传输。流水线传输就是发送方可连续发送多个分组,不必每发完一
个分组就停下来等待对方确认。这样可使信道上一直有数据不间断的在传
送。这种传输方式可以明显提高信道利用率
- 发送窗口 发送方维持一个发送窗口,凡位于发送窗口内的分组可以连
续发送出去,而不需要等待对方确认 - 累积确认 接收方一般采用累计确认,对按序到达的最后一个分组发送
确认,表明到这个分组为止的所有分组都已经正确收到了
累积确认的优缺点?
- 优点 容易实现,即使确认丢失也不比重传,因为累积确认还未重传就
收到更高序列的确认 - 缺点 不能向发送方反映接收方已经正确收到的所有分组的信息
TCB
传输控制块TCB存储每一个连接中的一些重要信息,包括TCP连接表,指向
发送和接收缓存的指针,指向重传队列的指针,当前的发送和接收序号
发送缓存和接收缓存
- 发送缓存
- 发送应用程序传送给发送方TCP准备发送的数据
- TCP已发送出当尚未收到确认的数据
- 接收缓存
- 按序到达但尚未被接受应用程序读取的数据
- 未按序到达的数据
流量控制
- 流量控制是数据链路层的一种功能,流量控制对数据链路上的帧的发送
速率进行控制,以使接收方有足够的缓冲空间来接受每个帧 - 流量控制的基本方法是由接收方控制发送方发送数据的速率
- 常见的流量控制方式:滑动窗口协议
拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部
分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过
多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载
。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷
。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,
以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对
点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发
送端发送数据的速率,以便使接收端来得及接收
流量控制和拥塞控制的区别
- 拥塞控制是让网络能够承受现有的网络负荷,是一个全局性的过程,
涉及所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因
素 - 流量控制往往是指点对点的通信量的控制,即接收端控制发送端,它
所要做的是抑制发送端发送数据的速率,以便使接收端来得及接收
TCP滑动窗口机制
- 滑动窗口的作用是提供TCP 可靠性:对发送的数据进行确认以及流量控
制:窗口大小随链路变化 - TCP中窗口大小是指tcp协议一次传输多少个数据。因为TCP 是一个面向
连接的可靠的传输协议,既然是可靠的就需要传输的数据进行确认 - TCP窗口机制有两种,一种是固定窗口大小,另一种是滑动窗口。数据在
传输时,TCP会对所有数据进行编号,发送方在发送过程中始终保持着一个
窗口,只有落在发送窗口内的数据帧才允许被发送,同时接收方也始终保
持着一个接收窗口,只有落在窗口内的数据才会被接收。这样通过改变发
送窗口和接收窗口的大小就可以实现流量控制 - TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,
保证接收方来得及接收。 接收方发送的确认报文中的窗口字段可以用来控制
发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发
送方不能发送数据,保证流量传输不超过设备的负载能力
固定窗口机制
需要对每个数据包都进行一个确认
- 如果说窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行
确认,这个时候就会造成很大的延迟 - 如果说窗口的大小定义的过大。我们假设发送方一次发送100个数据。但是
接收方只能处理50个数据。这样每次都会只对这50个数据进行确认。发送方下
一次还是发送100个数据,但是接受方还是只能处理50个数据。这样就有不必
要的数据来拥塞我们的链路
滑动窗口大小机制
窗口的大小并不是固定的而是根据我们之间的链路的带宽的大小、链路是否拥
塞、接受方是否能处理这么多数据,三个元素共同决定。不需要对每个数据包
进行确认,而是可以进行累积确认
- 第一次发送数据这个时候的窗口大小是根据链路带宽的大小来决定的
- 窗口大小指的是可以发送数据包的最大数量。在实际使用中,它可以分为
两部分。第一部分表示数据包已经发送,但未得到确认应答包,第二部分表
示允许发送,但未发送的数据包。在进行数据包发送时,当发送了最大数量
的数据包(窗口大小数据包),有时不会同时收到这些数据包的确认应答
包,而是收到部分确认应答包 - 此时窗口就通过滑动的方式,向后移动,确保下一次发送仍然可以发送窗
口大小的数据包。这样的发送方式被称为滑动窗口机制
滑动窗口的优势
- 允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每
发送每确认,因此该协议可以加速数据的传输 - 在接收窗口向前滑动时(与此同时也发送了确认),发送窗口也会同步向
前滑动,收发两端的窗口按照以上规律不断地向前滑动,可以动态调整窗口
大小
Nagle算法
当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度,就
立即发送一个报文段
拥塞控制的方法
判断网络拥塞的依据是出现了超时
- 慢开始 慢开始算法的思路是一开始不发送大量数据,由小到大逐渐增大发
送窗口,cwnd初始值为1,每经过一个传播轮次,cwnd加倍直到达到阈值 - 拥塞避免 达到阈值后使用拥塞避免算法,拥塞避免算法的思路是让拥塞
窗口cwnd缓慢增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwnd
加1,而不是加倍增长。当出现网络超时调整阈值为之前的一半,同时设
置拥塞窗口为1,进入慢开始阶段。如果发送方一连收到3个对同一个报
文段的重复确认,通过快重传算法知道这是丢失个别报文段,于是不
启用慢恢复而是快恢复 - 快重传 快速重传算法可以让发送方尽早知道发生了个别报文段的丢失,
要求接收方不要等待自己发送数据时才捎带确认,而是立即发送确认。如果
没有收到M3,那么就需要发送对M2的重复确认,发送方只要连续收到3个重
复确认就会立即进行重传 - 快恢复 将门限和拥塞窗口的值调整为当前的一半,并开始拥塞避免算法
拥塞窗口与流量窗口的区别
滑动窗口位于传输层(区别于数据链路层的),拥塞控制更关注网络层
- 滑动窗口 接受数据端使用的窗口大小,用来告知发送端接收端的缓存
大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的 - 拥塞窗口 防止过多的数据注入到网络中,这样可以使网络中的路由器或
链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络
负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与
降低网络传输性能有关的所有因素 - 发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再
增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就
减小一些,以减少注入到网络中的分组数
数据包的合成是在哪里进行?
在发送缓冲中进行
开启Nagle的好处与坏处
- 优点 避免网络中充斥着许多小数据块,降低网络负载,减少网络拥塞,提
高网络吞吐 - 缺点 客户端的延迟会增加,实时性降低,不适合延时要求尽量小的场景,
且对于大文件传输这种场景,会降低传输速度 - 大文件传输的情况下,因为文件数据移入输出缓存耗时很小,所以不用
nagle算法也会在装满缓存时才会发送数据,因此不仅不会增加数据包的网
络流量,反而无需等待ACK就可以传输,因此这种情况不使用nagle可以大
幅提高速度
什么是TCP粘包?
发送方发送的若干数据,在接受方接受时这些数据粘在了一起(一包)。从接
收缓冲区来看,后一包数据的头紧接着前一包数据的尾。 这种现象被称作
TCP的粘包问题
沾包的类型?
- 粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是
粘在一起的包有不完整的包 - 不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据
(如文件传输),则不必把粘连的包分开(简称分包) - 在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结
构数据的粘包问题时,分包算法就比较复杂
TCP粘包产生的原因?
粘包产生的原因可能由发送方造成,也可能由接收方造成
- 发送方 发送端为了将多个发往接收端的包,更加高效的的发给接收端
,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的
数据,合并成一个数据量大的数据块,然后进行封包。而Nagle算法是造
成发送方出现沾包问题的主要原因 - 接收方 TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应
用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然
后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓
存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应
用程序就有可能读取到多个首尾相接粘到一起的包
TCP粘包如何解决?
- 对于发送方:可以通过编程设置来关闭Nagle算法,使用TCP提供的强制
数据立即传送的操作指令push。但这样会降低发送效率,影响程序性能,所
以这个方法并不推荐使用 - 对于接受方:只能通过优化程序设计等措施保证接收方及时接收数据。但
这种方法只能减少粘包出现的可能性,并不能完全防止粘包问题的发生,所
以并不能算做成一个解决方案 - 应用层:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,
就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每
条数据的长度呢?
格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易
行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符
和结束符发送长度:发送每条数据时,将数据的长度一并发送,例如规定
数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分
组的开始和结束位置 - 在数据包中添加长度的方式,即在数据包中的固定位置封装数据包的长度
信息,服务器接收到数据后,先是解析包长度,然后根据包长度截取数据包
UDP存在粘包问题吗?
- TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了
基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界
的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,
接收端一次只能接受一条独立的消息) - UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条
独立的信息,所以不存在粘包问题
TCP拆包产生的原因和解法方法是什么?
产生原因如下
- 要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包
- 待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包
沾包和拆包如何解决?
解决方法如下
- 使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获
取消息头的时候解析出消息长度,然后向后读取该长度的内容 - 设置定长消息,服务端每次读取既定长度的内容作为一条完整消息,当消
息不够长时,空位补上固定字符,这样接收端每次接收缓冲区中读取固定长
度的数据就自然而然的把每个数据包拆分开来 - 设置消息边界,服务端从网络流中按消息边界分离出消息内容,一般使用\n
- 更为复杂的协议,车联网协议 808,809 协议
TCP和UDP的区别?各自的应用场景
- TCP应用场景:效率要求相对低,但对准确性要求相对高的场景。因为
传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。文
件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录 - UDP应用场景:效率要求相对高,对准确性要求相对低的场景。QQ聊天、
在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不
是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、
多播)
如何实现可靠的UDP?
传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以
参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层
- 添加seq/ack机制,确保数据发送到对端
- 添加发送和接收缓冲区,主要是用户超时重传
- 添加超时重传机制
有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT
- RUDP RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制
及淡化服务器算法等 - RTP RTP为数据提供了具有实时特征的端对端传送服务
- UDT UDT的主要目的是支持高速广域网上的海量数据传输
四次挥手中客户端的 TIME-WAIT 的状态的意义是什么?
- 可靠地实现TCP全双工连接的终止 最终的ACK是由主动关闭连接的一端(
后面统称A端)发出的,如果这个ACK丢失,对方(后面统称B端)将重发出
最终的FIN,因此A端必须维护状态信息(TIME_WAIT)允许它重发最终的
ACK。如果A端不维持TIME_WAIT状态,而是处于CLOSED 状态,那么A端将
响应RST分节,B端收到后将此分节解释成一个错误,为了TCP打算执行必
要的工作以彻底终止某个连接两个方向上的数据流(即全双工关闭),
那么他必须要正确处理连接终止四个分节中任何一个分节丢失的情况 - 允许老的重复分节在网络中消逝 因为TIME_WAIT状态持续2MSL,就可以
保证当成功建立一个新TCP连接的时候,来自旧连接重复分组已经在网络中
消逝
什么是Socket?
socket是对TCP/IP协议的封装,它的出现只是使得程序员更方便地使用TCP
/IP协议栈而已。socket本身并不是协议,它是应用层与TCP/IP协议族通信
的中间软件抽象层,是一组调用接口(TCP/IP网络的API函数)
- 服务端需要建立 socket 来监听指定的地址,然后等待客户端来连接。而
客户端则需要建立 socket 并与服务端的 socket 地址进行连接 - 调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数
据交换
什么是半关闭?什么是半打开?
- 半关闭 当TCP链接中A向B发送FIN 请求关闭,另一端B回应ACK之后,并没
有立即发送FIN 给A,A方处于半关闭状态。此时A可以接收B发送的数据,但是
A已经不能再向B发送数据 - 半连接 如果A向B发起链接,B也按照正常情况响应了,但是A不进行三次握
手,这就是半连接。半连接攻击:半连接,会造成B分配的内存资源就一直这么
耗着,直到资源耗尽。(SYN攻击) - 半打开 如果一方关闭或者异常关闭,而另一方并不知情,这样的链接称之
为半打开,如果需要发数据的话,这边收到之后 其实发现这个连接并不存在
了,就会回复RST包告知,这个时候就需要重新建立连接了
客户端的close-Wait是什么时候开始的?
- 主动关闭的一方发出FIN 包,被动关闭的一方响应ACK 包,此时被动关闭
的一方就进入了CLOSE_WAIT 状态。如果一切正常,稍后被动关闭的一方也会
发出FIN 包,然后迁移到LAST_ACK 状态 - 通常CLOSE_WAIT 状态在服务器停留时间很短,如果你发现大量的
CLOSE_WAIT状态,那么就意味着被动关闭的一方没有及时发出FIN 包
- 程序问题:如果代码层面忘记了 close 相应的 socket 连接,那么自然不
会发出 FIN 包,从而导致 CLOSE_WAIT 累积 - 响应太慢或者超时设置过小:如果连接双方不和谐,一方不耐烦直接timeout
,另一方却还在忙于耗时逻辑,就会导致 close 被延后
客户端接收到了服务器的close请求了,客户端不调用close,继续发包会怎么样?
根据TCP协议的规定,认为它是一个异常终止连接,客户端将会收到一个RST
复位响应(而不是ACK响应),如果客户端再次向服务端发送数据,系统将会
发送一个SIGPIPE信号给客户端进程,告诉客户端进程该连接已关闭,不要
再写了。系统给SIGPIPE信号的默认处理是直接终止收到该信号的进程,所
以此时客户端进程会被极不情愿地终止
为什么挥手不可以三次?
为什么是四次挥手,因为如果只进行了1、2次。由于TCP是全双工的,可以处于
Half-Close状态,此时就是处于Half-Close状态,客户端到服务器的通道已
经关闭,服务器到客户端的通道还没关闭,所以需要第三次和第四次来完全关
闭连接
如何设计http2.0的头部压缩(说了哈夫曼编码或者字典树)
- hpack表 把经常使用的头部键值对进行表格化(可以理解为数据缓存),
使其可以通过索引进行数据关联。如果头部键值已经存在直接使用索引进行
传输,对方便可解析对应数据内容
描述一下TCP是怎么发送文件的?
- 当你把要传送的数据传递给TCP后,TCP把文件按照MTU的大小分成一个个
包分成很多个数据包(这种数据包称为TCP分组),每一个分组都包含有一个
序号 - 接着TCP分组被传递给IP层,IP层把这个TCP分组放在一个IP数据包的数
据部分。然后,这个IP数据包被传到目的主机
Chrome 为什么多进程而不是多线程?
- Chromium里有三种进程——浏览器、渲染器和插件
- 有一种情况是多个页面使用同一进程,这就是同一站点
- 同一站点“定义为根域名加上协议,还包含了该根域名下的所有子域名
和不同的端口 - Chrome 的默认策略是,每个标签对应一个渲染进程。但是如果从一个页
面打开了新页面,而新页面和当前页面属于同一个站点,那么新页面会复用
父页面的渲染进程 - 如果几个页面属于同一站点,那么他们将会被分配到同一个渲染进程中
,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同
一个渲染进程 - 因为在一个渲染进程中,他们就会共享 JS 的执行环境
TCP有了checksum还可能会造成数据错乱吗
有可能
- 因为可能错误的数据凑成了正确的校验和。任何检测误差的方法都是有
他的极限的,错太多了就不行了 - 校验和本身传输的时候出错了
为什么初始化序列号要随机取,从0开始会出现什么问题?
- 假定主机A和B频繁地建立连接,传送一些TCP报文段后,再释放连接,然
后又不断地建立新的连接、传送报文段和释放连接,假定每一次建立连接时
,主机A都选择相同的、固定的初始序号,假定主机A发送出的某些TCP报文
段在网络中会滞留较长的时间,以致造成主机A超时重传这些TCP报文段,
假定有一些在网络中滞留时间较长的TCP报文段最后终于到达了主机B,但
这时传送该报文段的那个连接早已释放了.而在到达主机B时的TCP连接是
一条新的TCP连接,因此必须使得迟到的TCP报文段的序号不处在新的连接
中所使用的序号范围之中 - 如果TCP每次连接都使用固定ISN,黑客可以很方便模拟任何IP与server
建立连接,抓包只能发生在同一网络中,随机ISN能避免非同一网络的攻击
流量控制和拥塞控制有什么区别?
- 流量控制解决的是发送方和接收方速率不匹配的问题,发送方发送过快接
收方就来不及接收和处理。采用的机制是滑动窗口的机制 - 拥塞控制解决的是避免网络资源被耗尽的问题,通过大家自律的采取避让
的措施,来避免网络有限资源被耗尽。当出现丢包时,控制发送的速率达到
降低网络负载的目的 - 流量控制是通过滑动窗口来实现的。 滑动窗口分为发送端窗口和接收端窗
口,窗口大小是接收端用来告诉发送端目前接收端能接收的最大字节数 - 拥塞控制是通过拥塞窗口来实现的。拥塞窗口指发送端在一个RTT内可以最
多发送的数据包数 - 滑动窗口是接收方的流量控制,拥塞控制是发送方的流量控制