本文内容:
- TCP与UDP的区别?
- TCPTCP如何保证可靠性?UDP如何实现可靠性?
- TCP如何提高性能?
- TCP报文
- TCP连接
- TCP的一些问题
TCP与UDP的区别?
TCP UDP 传输格式 面向字节流 面向数据包 是否面向连接 面向连接,传输数据前,先建立连接,只支持一对一 直接传输数据,支持一对一、一对多、多对多 传输性能 延迟小,传输性能高 可靠性 保证 不保证 应用场景 HTTP、银行应用 QQ消息,语音、视频、广播
TCP如何保证可靠性?
数据在网络传输时,由于网络环境的复杂性,可能丢包、超时、损坏,可靠性就是解决这两个问题
解决方法:字节号+确认+超时重传+校验码
- 给字节编号,让接收端进行ACK确认,对超时未收到确认的字节进行重传
- 校验码保证数据传输过程中没有损坏
UDP如何实现可靠性?
应用层来实现确认、重传,如QQ发消息,上层实现可靠性--丢包处理
- 可靠性:收一个包,确认一次
- 有序:记录最大序号,比它小的扔掉
TCP如何提高性能?
滑动窗口:一轮传输多个TCP段
捎带应答:ACK+自己要发的消息
Nagle算法:将多个小段合并发送
拥塞控制
流量控制
流量控制(接收方发送接收窗口大小)
发送窗口大小=Min(接收窗口,拥塞窗口)
零值计时器 --- 0窗口探测
拥塞控制
- 几个名词:
- RWND:接收窗口,CWND:拥塞窗口,SWND:发送窗口 = min(CWND,RWND)
- ssthresh:慢开始阈值
- IW:初始CWND窗口大小
- SMSS:发送方最大段大小,一般等于MSS
- FlightSIze:已发送但未确认字节数
- 慢开始
- 发送数据分段前先试探下网络情况
- 设定拥塞窗口为1,每经过一轮传输后,成倍增长窗口大小
- 拥塞避免
- 每经过一轮传输后,窗口大小增长1
- if 拥塞窗口大小<慢开始阈值 : 执行慢开始算法
- else :执行拥塞避免算法
- 快重传
- 超时重传:每发送一个数据分段启动一个超时计时器,超时后还没收到ACK确认,则重发
- 重复确认:
- 接收方收到一个分段后,发送的ACK是它期待的下一个数据分段的序列号
- 如果某个分段丢失,接收方收到了不是希望收到的分段,而是它的下一个分段,则会再次发送之前发出的ACK
- 快速重传:当出现超过重复阈值的重复确认后,不必等超时计时器,立刻重传
- 快恢复
- 快重传后,修改慢开始阈值,并设定拥塞窗口为这个值,执行拥塞避免
- 拥塞判定
- 超时--定时器溢出
- 设定慢开始阈值=max(MSS*2, 已发送未确认字节数)
- CWND <= SMSS,重新慢开始
- 收到3次重复的确认
- 快速重传,不等超时了
- 设定慢开始阈值=max(MSS*2, 已发送未确认字节数)
- 设定CWND=慢开始阈值
TCP,UDP报头
固定部分20字节+可选选项(44字节) = 最多64byte
- 16bit源端口号,16bit目标端口号
- 32bit SYN序列号
- 32bit ACK
- 4bit length, 6bit 保留字, 6bit 标志位;16bit 接收窗口大小
- 16bit 校验和, 16bit紧急指针
- 44byte选项(最大段尺寸)
- MSS的作用:Max Segment Size,指每次能够传输的最大数据分段(一般等于MTU最大传输单元),是用来避免IP分片的
- 由于IP层不提供超时重传,IP分片如果丢失会导致整个TCP报文重传
- 所以TCP自己分段,就能出现丢失时对一段进行重传,而不是整个报文重传
UDP固定8字节
- 16bit源端口号,16bit目标端口号
- 16bit 报文长度, 16bit 校验和
TCP连接
连接状态转化图
TIME_WAIT
- 作用,为什么需要2MSL(maximum survival lifetime)?
- 最后的ACK的超时重发
- 让上一个连接的报文以及对它的应答消亡
- 客户端大量TIME_WAIT
危害:占内存,一个TIME_WAIT占用4k大小;端口占用
解决措施:
修改内核配置:
tcp_timestamp,发送数据段时会带上时间戳,对方ACK里会保留时间戳,收到ACK后用当前时间-这个来计算RTT
tcp_tw_recycle,复用TIME_WAIT状态的socket,如果收到旧消息时间戳<于新连接创建时间,则丢弃
短连接-->长连接:一次连接处理多次请求
比如http复用TCP连接
TCP的一些问题
- TCP缓冲区的作用
- 接收缓冲区:TCP是以字节流形式传输,等数据完整抵达
- 发送缓冲区:超时重传,ACK后的字节删掉,确保可靠传输
- 单机服务器的最大并发TCP连接数?
理论上是2^48 = IP地址数*客户端口数,实际中受到下列因素的影响
- 系统允许的文件句柄数
- 进程打开文件的限制
- 端口号
- TCP连接的目的是什么?
- 在传输数据前先确认对方存在,能正常接收;
- 相互交换对方即将发送数据的序列号
- 随机初始序列号的作用?
- 防止旧连接的报文对新连接产生影响
- 假如固定初始序列号,旧连接的报文迷路了,然后旧连接因为意外关闭了,再开一个新连接,旧报文又抵达了
- 防止伪造序列号攻击
- 假定按时钟递增序列号,容易被攻击者试探出来,然后伪造TCP段进行攻击
- 如何处理TCP粘包?recv(指定socket,缓存区,取的最大长度)
- 应用层处理,流to包的转换
- 应用层报文定长或带上长度
- 添加特殊消息终止标志
- 三次握手最后一次ACK丢失? 服务器如何处理之前的数据包?
- 服务器:重发SYN+ACK,直到超时重传次数达到,关闭连接
- 客户端:进入ES完成状态,向服务器发送数据,收到RST复位后关闭
- ISN初始序列号为什么要随机?
- 防止旧连接的包重新出现
- 防止被黑客预测然后攻击
- 防止最先的数据包丢失?
- 半连接是指?
- 某一方连接意外关闭,另一方不知道,往半打开连接发数据时,关闭那方会发一个RST复位
- 客户端挂了怎么办?
- 心跳包
- 连接的作用
- 让对方知道自己的序列号,要不可能最早发的丢了
- 试探
- 为什么视频用UDP传输
- 强调传输性能,而不是传输可靠性