TCP/IP四层中常见协议Ⅱ—传输层

2019-12-05 0 条评论 23 次阅读 0 人点赞

传输层:UDP/TCP

UDP——用户数据报协议:无连接,不可靠,面向数据报

协议字段

  • 16位源端口 & 16位目的端口:描述数据从哪个进程来,到哪个进程去
  • 16位校验和:二进制反码求和算法——校验接收到的数据与发送的数据是否完全一致
  • 16位数据报长度:包含头部在内的udp数据报的长度,决定数据只能整条发送,整条交付

无连接,不可靠

客户端只需要知道服务端的地址信息就可以直接发送数据,并且不关心数据是否已经到达

面向数据报

  1. 特性取决于udp数据报长度字段,uin16_t决定了udp整个数据报长度不能大于64k,否则两个字节不够存储。
  2. 由于udp数据报长度的限制,若数据过大则需要用户在应用层进行数据分包,将数据分割成小的数据包64k-28
  3. udp并不保证数据的可靠、有序到达,有可能产生乱序,需要用户在应用层进行包序管理
  4. udp在sendto(buf, len)接口发送数据时将数据放到发送缓冲区,会直接封装头部,将数据发送出去(每一次sendto发送的数据都会封装一个udp头部)

应用:

不能应用于有安全性要求的传输,但是因为报头短并且不需要保证可靠传输,因此传输速度快

应用于实时性要求高的场景

udp在协议栈层面实现了广播功能:通过向一个IP地址发送数据,实现将数据发送到局域网所有主机

在传输层基于UDP实现的应用层协议:DHCP,DNS

TCP——传输控制协议:面向连接,可靠传输,面向字节流

协议字段:

  • 16位源端口 & 16位目的端口:负责端与端之间的数据传输
  • 32位序号&32位确认序号:进行tcp协议栈中的包序管理+其他功能
  • 4位首部长度:长度单位是4个字节,范围20~15*4个字节
  • 6位标志位:URG/ACK/PSH/RST/SYN/FIN
  • 16位窗口大小:滑动窗口,用于避免丢包的一种方式
  • 16位校验和:校验数据一致性,二进制反码求和
  • 16位紧急指针:带外数据
  • 40字节数据选项:通常通信双方协商一些信息时使用

面向连接

双方通信之前需要先建立连接

1. 握手为什么是三次,不是两次或四次?

握手三次是因为只握手两次不安全,而握手四次没必要:tcp是一个双工通信,需要双方都确保对方具有数据收发的能力,客户端发送SYN请求后若客户端退出,服务端不进行一次确认的话发送数据就会产生丢包。第一次的SYN若因网络延迟与后来的第二个SYN同时到来,会造成服务端创建多余的socket

2. 挥手为什么是四次?

  1. 套接字的关闭有好多操作,shutdown(fd, SHUT_RD/WR)分别可以关闭套接字的读和写,而其中当关闭套接字写操作时,会触发向对端发送FIN报,接收方收到FIN后,认为不再继续发送数据,因此recv会返回0,等待用户关闭套接字(CLOSE_WAIT),关闭套接字则会给对方发送FIN包
  2. 在发送端若是之关闭了写端,并没有关闭套接字读端,意味着对端有可能还在发送数据,自己有可能还需要接收,因此FIN和ACK不能一起发送,否则自己在部分数据还没接收成功的情况下发送FIN,可能会导致数据没有处理完毕或对端数据发送不完整的情况。
  3. 因此挥手不能三次必须四次。

3. TIME_WAIT有什么用?不要TIME_WAIT可以吗?

  1. 若主动关闭方没有TIME_WAIT:closed最终释放socket,该socket不在占用地址信息。此时若立即启动一个客户端创建里socket有可能使用跟上一个socket相同的端口。
  2. 此时若上一个客户端的最后一次挥手发送的ACK丢失,对端会重新发送FIN包
  3. 新启动的客户端有可能会接受到这个FIN包,对新连接造成影响
  4. 新启动的客户端向服务端发送SYN就会被认为状态错误,重置连接

因此,在主动关闭方发送最后一个ACK后,必须等待一段时间

  1. 在等待期间重发的FIN包就可以重新回复一次ACK

  2. 等待而不能此通信的所有数据都消失在网络之中,避免对后续连接造成影响;

    等待的时间是2个MSL(报文的最大生命周期)时间。

4. 服务端主机上出现了大量TIME_WAIT连接是什么原因?怎么处理?

  1. 服务端大量关闭了客户端套接字

  2. 调整TIME_WAIT等待时间

  3. 地址重用setsockpt(int sockfd, int level, int name, int opt, int optlen)

    level:SOL_SOCKET,套接字选项设置

    name:SO_REUSEADDR,地址重用(重新使用相同地址)选项

    options:开启/关闭选项,int options = 1

    len:options数据长度

tcp协议栈中连接管理中的保活机制:`sysctl -a |grep keepalive

若通信双方长时间(7200s)无数据往来,则会每隔一段时间(75s)给对方发送一个保活探测数据报,要求对方进行恢复,若多次(9次)保活探测请求没有得到恢复,则会认为链接已经断开,将socket状态置为CLOSE_WAIT,程序当中recv返回0,send触发SIGPIPE异常

可靠传输

  1. 面向连接

  2. 确认应答机制:发送的每一条数据都要求对方进行确认回复

  3. 超时重传机制:等待确认回复超时,则重发数据

  4. 协议字段中的序号/确认序号

    数据的确认恢复还有一个作用:确认序号一定是保证在这个序号之前的所有数据都已经收到了;
    若第一条数据没有收到,就算收到了第二条数据也不会对第二条数据进行确认回复,每一条回复都要保证在这之前的数据已经完全收到

  5. 协议字段中的校验和

TCP为了实现可靠阐述牺牲了部分性能

如何避免丢包

  1. 滑动窗口机制:通过一个窗口后沿(保存序号的变量)和一个窗口前沿以及一个当前的发送序号维护一个窗口。

    在tcp三次握手阶段,通信双方会协商一个MSS最大数据段大小;用户send发送数据会将数据放到发送缓冲区中,然后操作系统会从缓冲区中每次取出不大于MSS大小的数据,封装TCP头部发送出去。

    TCP在每次发送数据的时候,都会给对方在报文头部中发送一个字段:16位窗口大小,用户告诉对方最多一次给自己连续发送多少数据,窗口大小不得大于接收缓冲区中的剩余大小。

    对于发送窗口:前沿减去后沿 不能大于 接收方返回的窗口大小;后沿的移动取决于是否收到相应的数据ACK确认回复;前沿的移动取决于接收方会返回的窗口大小。

    对于接收窗口:窗口大小不大于缓冲区剩余空间大小;后沿的移动(当前接收数据的起始序号位置)取决于是否收到数据;前沿的移动取决于缓冲区空闲空间的大小

    好处:

    1. 发送方可以连续发送多条数据,等待对方回复,提高一定的传输性能
    2. 连续发送数据,连续接收确认回复可以避免因为确认回复丢失而导致数据重传(每一条确认序号都需要保证在这之前的数据都已经安全到达)
    3. 流量控制:接收方通过每次收到数据后的确认回复向对端传递窗口大小,即接收缓冲区中剩余空间大小,限制对方最多能发送的数据,避免因发送的数据过多导致接收缓冲区满溢后数据丢包。
  2. 快速重传机制:当接收方接收到了第二条数据,却还未收到第一条数据,则认为数据有可能丢失,因此连续发送三次对应数据的重传请求;当发送方连续接受到三条重传请求时,才会将相应数据进行重传,避免数据因网络原因延迟到达而重传。

  3. 拥塞控制:慢启动,快增长,避免因网络状态不好而导致的大量丢包

如何提高性能

  1. 延迟应答机制:接收方接受到数据之后不会立即进行确认回复,延迟一会进行确认回复,以此尽可能保证窗口大小(在延迟期间,用户有可能调用recv将数据从缓冲区中取走) 保证数据通信吞吐量不被降低,而导致传输速度降低。延迟时间不会太长,一般不超过500ms
  2. 捎带应答机制:接收方每接收一条数据就要进行确认回复,而确认回复就是一个tcp报头。通过在即将发送的数据头部中将上次的确认回复捎带上,可以减少纯报头的确认回复

面向字节流

有序、可靠、双向、基于连接的字节流传输

tcp中send发送数据会先将数据放入发送缓冲区中,操作系统从缓冲区中取出合适大小(MSS)的数据封装头部发送

TCP粘包问题

TCP在传输层对数据边界不敏感(不管数据是什么类型,也不管数据有多少,只管发送合适大小的数据),多条数据合成一条数据进行处理(发送/交付给用户)。粘包有可能在发送端产生也可能在接收方产生

如何解决粘包

产生粘包的本质原因是TCP在传输层对数据边界不敏感,需要用户在应用层进行数据边界的管理

解决方案

  1. 数据定长
  2. 特殊字符进行间隔
  3. 在不定长数据的应用层头部添加数据长度字段

UDP是不存在粘包问题的:在不定长数据的应用层头部添加数据长度字段

面向字节流与面向数据报

面向字节流:数据都子啊缓冲区中,如何发送接收(recv/send)都由用户自己定,传输比较灵活,但是存在粘包问题

面向数据报:数据只能整条收发,不够灵活,但是不存在粘包问题

应用:

在传输层基于TCP协议的应用层协议:HTTP/FTP

TCP如何实现可靠传输?

  • 面向连接:确认应答机制,超时重传机制,序号/确认序号,校验和
  • 避免大量丢包:滑动窗口机制(流量控制),快速重传机制,拥塞控制
  • 提高传输性能:捎带应答机制,延迟应答机制

TCP协议你知道多少?

TCP协议是TCP/IP协议栈中的一个传输控制协议,它的特性主要是面向连接,可靠传输,面向字节流。其中面向连接主要是通过三次握手与四次挥手来进行连接管理,并且通过当中的状态标记连接中的信息变化,维持这个连接;
可靠传输是为了保证数据可靠的到达对端,首先是建立连接之后再进行通信,连接建立之后利用确认应答机制和超时重传机制保证数据能够到达对端,利用协议当中的序号和确认序号进行包序管理,以此保证数据有序到达,利用数据校验和校验发送与接收的数据一致,一致数据就丢弃并要求数据重传。
TCP为保证数据可靠传输,牺牲了一部分性能,所以要提高他的性能,首先是使用滑动窗口机制避免丢包重传,在这个机制中主要是通过流量控制防止传输数据过快,接收数据过慢而导致的接收缓冲区满溢产生的数据丢包,还有使用拥塞控制以慢启动,快增长的方式向对端传输数据,避免因网络状态差而导致的丢包。再利用快速重传机制,在传输过程当中若接收到了后面的数据却还没有接收到前面的数据,就会发送三次重传请求,同样在一定程度上避免丢包造成的性能下降。利用捎带应答机制减少数据回复时不必要的空报头传输。使用延迟应答机制保证网络吞吐量不会降低,数据传输速度不会受影响。

udp如何实现可靠传输?

在应用层实习TCP的可靠传输机制

L_KingMing

这个人太懒什么东西都没留下

文章评论(0)