传输层:负责应用之间的数据传输(通过端口的描述 - -描述哪两个进程在进行通信)- -UDP/TCP
UDP:无连接,不可靠,面向数据报
udp协议格式:
特性解析:
无连接:不需要建立连接,只要知道对方的地址信息就能直接发送数据
不可靠:udp在传输层不保证数据安全有序的到达对端- - -需要程序员在应用层进行包序管理
面向数据报:有最大长度限制的传输方式- - -取决于数据报长度字段,因为长度字段只有16位,因此数据报总长度不能大于64k,因此若要传输的数据比较大,则需要程序员在应用层进行分包操作,并且进行包序管理
udp通信在报头中确定了数据报长度,因此udp的数据传输时整条收发的
发送:sendto给与的数据放到发送缓冲区后就会直接封装头部,进行发送
接收:recvfrom总是只能接受一条完整的数据,而不会出现接收半条或者多条的情况
因此recvfrom给与的缓冲区一定要足够打,若给与的缓冲区大小小于一条数据的长度,则recvfrom就会报错(udp无法交付半条数据)
TCP:面向连接, 可靠传输, 面向字节流
tcp协议格式:
面向连接:连接建立成功之后才能进行数据通信- - -tcp有自己的连接管理- - 三次握手建立连接/四次挥手断开连接
1.为什么握手是三次?而挥手是四次?
①.握手2次不安全,4次没必要
tcp通信需要确保双方都具有数据收发 的能力,因此双发都要发送SYN确保 对方具有通信能力
②.为什么挥手是四次而不是三次:发送FIN包,只能表示对方不再发送数据,不表示对方不再接收数据,因此被动关闭方进行ACK回复之后可能还会继续发送数据,等到不再发送数据了,才会发送下一个FIN包,因此FIN和ACK是分开的
2.TIME_WAIT状态有什么用?
假设主动关闭方最后一次ACK丢失,被动关闭方没有收到最后一次ACK,超时就会重传FIN
假设客户端没有TIME_WAIT就直接释放资源,就有可能启动新客户端与之前客户端相同地址信息
①.刚启动的新的客户端绑定地址成功,收到重传的FIN包,对新连接造成影响
②.新启动的客户端,若是向相同的服务端发送SYN请求,因为服务端处于LAST_ACK而不是SYN,因此就会发送RST
因此若主动关闭方最后一次回复后直接释放资源,就有可能会对新启动的新连接造成影响,因此等待一段时间,能够处理重传的FIN包,
等待的时间一般为:2个MSL时间 MSL:报文最大生存周期
3.tcp三次握手失败,服务端如何处理?
①.没有收到SYN,什么都不做 ②.回复了SYN+ACK,长时间没有响应,则超时后发送RST重置连接报文,释放资源
4.一台主机上出现大量的TIME_WAIT是什么原因?如何处理?
TIME_WAIT是主动关闭方出现的,一台主机出现大量的TIME_WAIT证明这台主机大量的主动关闭连接,常见于一些爬虫服务器
调整TIME_WAIT等待时间,也可以使用开启地址重用的套接字选项
5.一台主机上出现大量的CLOSE_WAIT是什么原因? 如何处理?
CLOSE_WAIT是被动关闭方收到FIN请求后进行回复的状态,等待上层程序进行进一步处理,若出现大量CLOSE_WAIT,有可能是被动关闭方主机上忘了最后一步断开连接后调用close释放资源
TCP连接管理中的保活机制:
tcp通信中,若两端长时间没有数据往来,则这时候每隔一段时间,服务端向客户端发送一个保活探测数据报,要求客户端进行回复,若连接多次没有收到响应,则认为断开连接
长时间没有数据来往:默认7200s----通过设置套接字选项配置
每隔一段时间:默认75s
连续多次无响应:默认9次
可靠传输:
1.面向连接
2.确认应答机制- - 发送数据后要求对方进行确认回复,才知道对方是否收到了这条数据,通过序号和确认序号实现
3.超时重传机制- - 发送数据等待确认响应时间之后,则认为数据丢失,则进行重新传输
4.通过序号/确认序号字段实现数据有序传输
5.通过校验和字段检验数据一致性,不一致则要求对方进行重新传输
seq:本条数据起始序号。
ack:对对方发送数据的确认序号,搞虚对方确认序号之前的数据我收到了
三次握手时,双方会协商起始序列号(例子从0开始,实际中不一定,是一个随机值),三次握手中,虽然数据长度为0,但是确认序列号是对方发送的数据起始号+1
数据通信时,确认序号是对方发送的数据中的起始序号加上数据长度,告诉对方这个确认序号之前的数据都已经收到了
数据连续发送时,第一条数据丢失,接收方直接收到第二条和第三条,接收方就不会对第二条和第三条进行回复,因为确认序号确认的是这个数据之前的数据全部都已经收到了,这么做的目的,防止因为确认回复的丢失而导致的重传,就算因为网络原因,后发的数据先到了,接收方也会根据协商的起始序号,根据每条数据中的起始序号,将数据在接收缓冲区中进行排序
额外的丢包问题处理:
1.发送方发送的数据过快,接受方来不及取出处理,接收缓冲区满溢,则以后的数据都会被丢弃
2.发送方发送大量数据,但是因为网络状态不好导致大量丢包重传
滑动窗口机制:依靠协议中的窗口大小字段实现流量控制
接收方通过协议中的窗口大小字段,告诉发送方最多可以发送多少数据(窗口大小不大于接收方的接收缓冲区剩余空间大小)
MSS:最大数据段大小,表示tcp数据通信时一条数据的最大大小,通信时双方进行协商,取双方中MSS较小的一方作为最大数据段大小
滑动窗口在发送方维护发送窗口/接收方维护接收窗口----窗口通过一个后沿序号/前岩序号实现
发送窗口:表示一次最多从后沿到前沿最多发送多少数据----不超过接收方的窗口大小
后沿:所要发送的数据起始序号,后沿的移动取决于是否收到数据确认回复
前沿:根据接收方窗口大小计算结束序号,取决于接收方响应的窗口大小(前沿减去后沿大小就等于接收的窗口大小)
接收窗口:表示从哪里开始接收数据,接收到多少序号为止,不超过剩余空间大小,进行包序管理,哪个包应该放在缓冲区的什么为止
后沿:接收数据的起始序号,后沿的移动取决于是否收到了新数据
前沿:根据接收缓冲区剩余空间大小计算得到接收的数据的结束序号
滑动窗口机制允许发送端根据窗口大小以及mss连续发送多条数据,一旦丢包:
停等协议:等到一条回复,然后才能发送下一条数据
回退n步协议:一条数据丢了,需要发送端将这条数据以后的数据都进行重传
选择重传协议:一条数据丢了,则仅仅针对丢失的数据进行重传
因为网络状态不好,导致发送的数据越多丢包就越多:拥塞控制
拥塞控制:进行网络探测,以一种慢启动,快增长的传输方式,进行根据网络状态调整发送速度的机制
提高传输机制的方法:
快速重传机制:发送端连续发送多条数据,若接收端接收数据并非是接收后沿数据,则认为有可能后沿数据丢失,首先不会进行接收到的数据的确认回复,其次向发送端间隔连续三次后沿数据的重传请求,要求对方对后沿数据进行重传,发送方连续收到三条同一重传请求,则对这条数据进行重传
延迟应答机制:接收方接收到数据之后,并不立即进行确认回复(因为如果进行确认回复,因为接收缓冲区剩余空间变小了,窗口变小了,导致传输的吞吐量变小了),而是延迟应答,则有可能应答的时候程序在上层以及将数据取出,保证窗口大小不会变
捎带应答机制:接收方接收到数据之后进行确认回复,确认回复就是一个报头中的确认序号进行的,为了减少空报头的响应占据带宽,使用捎带应答,在即将要发送的数据头部中进行上一条接收的数据的确认回复
面向字节流:字节流传输服务—面向连接的,有序的一种以最小以字节为传输单元的传输方式
发送端在send发送数据的时候,并不会立即封装报头,而是将数据先放到发送缓冲区中,选择合适的时候再去从缓冲区中取出合适大小的数据进行传输
接收端在recv接收数据的时候,并非一条一条向上交付,而是根据recv想要的数据长度从接收缓冲区中取出指定长度的数据进行发送
优点:传输比较灵活,大量小的数据集合合成一条大的数据进行一次性传输,减少了IO次数(延迟发送可以关闭,可配置),接收方也比较灵活,想要多少取多少
缺点:tcp交付的这条数据可能并非一条完整的数据,也有可能是多条数据(tcp对于上层给与的数据边界并不敏感,不关注是几条数据,只关注自己可以传输多少字节的数据/recv想要接收多少字节的数据----反之udp对于每条传输的数据都有边界区分,每次刚好只交付一条完整的数据),导致上层将多条数据当作一条数据进行处理
tcp的粘包问题:tcp有可能将多条数据当作一条数据进行处理(udp不会出现粘包问题,因为udp头部包含了数据报长度)
tcp粘包的解决方案:程序员在应用层进行数据的边界管理
1.每条数据之间以特殊字符进行间隔(缺陷:如果数据中有这个特殊字符,就需要转义处理)
2.数据定长传输(缺陷:数据短小的话就需要进行补位,传输了大量无用的数据)
3.在应用层协议头部中定义数据长度
http如何解决粘包问题:http头部以\r\n特殊字符作为间隔表述结束,并且在头部中通过Content
udp如何解决粘包问题:头部定长8字节,头部中定义数据报长度