美文网首页JAVAlinux工具Linux
网络知识梳理(后台开发人员面试必备)

网络知识梳理(后台开发人员面试必备)

作者: 东植George | 来源:发表于2017-07-21 16:45 被阅读1331次

    最近在处理一个TCP粘包问题,虽然相关的知识都略知一二,但是好像让我完整的说出来细节,却还要查下资料,因此,整理列出来,以便复习。而且这些知识点是后台开发人员的必备基本功,相当于内功,还是要多拿出来温故而知新。

    1.不同协议层的限制值:

    1.1 链路层(以太网)

    局域网(无线是另一种协议)采用CSMA/CD协议,核心概念就是

    通道共用,发送前监听冲突,冲突后重发

    标准以太网帧长度下限:64byte

    原理大概就是因为发送前要监听是否有其他人在使用通道,而根据通讯原理,64byte传输的时间就是知道是否有冲突的最小时间。

    标准以太网帧长度上限:1518byte

    这个值也是协议标准协会“拍脑袋”的结果。

    一方面,如果太小,每次传输的利用率就低(TCP头部20byte,IP头部20byte,链路层头部18byte);另一方面,如果太大,就会导致共享通道被某一方霸占太久,而且,包太大,出错率高,缓存成本也要提高。

    1.2 网络层

    MTU: 1500byte(TCP标准化采用576byte)

    因为“标准以太网帧长度上限”为1518byte,所以减去链路层18byte的头部,IP数据报的最大限制值就等于1500byte。

    IP分片

    注意和传输层的“数据报分段”区分。

    如果IP数据报长度大于MTU,就需要分成几段传输,然后重组,分片和重组都是在网络层协议完成的。

    因为TCP传输层才有提供超时和重传机制,网络层没有,所以如果有一片IP分片丢失,需要重传(TCP的重传),丢失的IP分片所属的TCP数据的所有IP分片,都要再重新传输。

    1.3 传输层(TCP)

    MSS

    每个TCP数据报(去掉IP头部和TCP头部)的最长长度。如果未设置,默认为536byte(对应MTU576byte),一般在以太网,都是1460byte(1500-20-20)。

    在TCP握手的前两次商议MSS值。

    TCP分段

    请区分 “TCP分段” 和 “IP分片”,两个是在不同协议层的概念。

    如果TCP数据长度超过MSS,就要分段,然后重组。

    因为MSS<MTU,所以TCP一般没有IP分片,而UDP和ICMP没有分段,所以就只能靠IP分片了。

    2. Nagle 算法

    Nagle算法

    为了解决telnet场景下,敲一下键盘就发送一个字符,传输效率低导致网络阻塞的问题。

    Nagle算法基本定义是:任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

    可以设置TCP_NODELAY来关闭,提高传输效率,缺点是实时交互性差。

    TCP确认延迟机制

    可以看出,Nagle算法受限于接收方发回ACK的时间间隔,因此与之配套的接收方使用“TCP确认延迟机制”。延迟默认为40ms,视情况调整数值。可以设置TCP_QUICKACK标志来关闭。

    3. TCP粘包

    为什么会出现TCP粘包?

    在Nagle算法的作用下,假设在等待ACK期间,发送一段文字“hello”,然后又发送了“world”,假设MSS为7,这时对方接收到的就是“hellowo”。消息黏在一起,所以称为“粘包”。

    解决方法:一般是使用标识来识别界限。加字段size来指明一个包的长度,或者是在一条数据的结尾加特殊的结束符(比如/n)。

    为什么UDP不会粘包?

    首先,在发送方,UDP没有Nagle算法来合并发送几个数据。

    然后接收方,UDP是基于消息保护边界,不同于TCP的基于流传输。也就是UDP会使用链式保持每条接收的完整消息。比如发送方发了3条消息,UDP接收方会在缓存独立保存3条消息,而TCP则可能只接收到一条合并的消息;UDP需要recv 3次才能接收3条消息,TCP则可能recv一次就行了。

    为什么UDP会采用链式保存接收到的消息?因为TCP是一对一的连接,而UDP是可能一对多的连接,为了区分不同发送方发来的消息,所以需要分开存放。

    4. 为什么UDP没有发送缓冲区

    首先需要大概了解一下TCP和UDP在执行write的原理

    TCP在write的时候,系统把消息从用户态拷贝到内核的socket发送缓冲区,然后直接返回成功,接下来会有一系列操作会用到缓冲区(丢失重传,Nagle算法的合并,滑动窗口等等)。直到收到对方的ACK,内核才会把消息从发送缓冲区删除。

    UDP在write的时候,因为是不可靠传输,所以只是把数据从用户态拷贝到内核,然后立即发送出去,不管对方是否能收到,所以不需要缓冲区。

    TCP和UDP都有接收缓冲区

    内核态和用户态的切换工作模式,决定了缓冲区的必要性。当然两种缓冲区的工作模式不一样。

    TCP如果缓冲区满了,会通过滑动窗口的流量控制告诉对方不要再发了,不然会丢掉新包。UDP则只是简单的丢掉。

    从缓冲区理解socket的阻塞和非阻塞操作

    从上面可以看到,不管是read或者write,操作其实都是消息在用户态和内核态的拷贝。因此,阻塞其实就是看内核缓冲区有没有数据。

    比如阻塞模式下,read会一直等待内核缓冲区有数据才返回,而非阻塞模式,则会立即返回;阻塞模式下,write会一直等待内核有足够空间写入数据才返回,而非阻塞模式,有空间则写入,没有就会告诉你失败。

    5. 三次握手和四次挥手

    为什么需要3次握手

    因为是建立一个全双工的连接,所以互相都要得到对方的确认,以及通信的双方要互相通知对方自己的初始化的Sequence Number,所以流程顺序应该是这样的:(1.A跟B说我要连接;2.B答应并且返回x+1;3.B跟A说要建立连接;4.A答应并且返回y+1。)

    总共有4个步骤,但是因为步骤2和3可以合并一起,所以就成了“3次握手”。

    注意:SeqNum的增加是和传输的字节数相关的,握手和挥手都是1个字节,所以才加一。

    如果A在执行步骤4之前就断开了,B会重发步骤3。在Linux下,默认重试次数为5次,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s才知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个连接。

    SYN flood攻击

    给服务器发了一个SYN后,就下线了,于是服务器需要默认等63s才会断开连接,这样,攻击者就可以把服务器的syn连接的队列耗尽,让正常的连接请求不能处理。

    于是,Linux下给了一个叫tcp_syncookies的参数来应对这个事——当SYN队列满了后,TCP会通过源地址端口、目标地址端口和时间戳打造出一个特别的Sequence Number发回去(又叫cookie),如果是攻击者则不会有响应,如果是正常连接,则会把这个 SYN Cookie发回来,然后服务端可以通过cookie建连接(即使你不在SYN队列中)。请注意,请先千万别用tcp_syncookies来处理正常的大负载的连接的情况。因为,synccookies是妥协版的TCP协议,并不严谨。

    对于正常的请求,你应该调整三个TCP参数可供你选择,第一个是:tcp_synack_retries 可以用他来减少重试次数;第二个是:tcp_max_syn_backlog,可以增大SYN连接数;第三个是:tcp_abort_on_overflow 处理不过来干脆就直接拒绝连接了。

    5. TCP滑动窗口

    TCP滑动窗口是网络流控的一种实现方法。接收方通过通知发送方自己的窗口大小,从而控制发送方的发送速度,达到防止发送方发送速度过快而导致自己被淹没的目的。

    由上图可以看出窗口的动态变化过程:

    1.一开始窗口大小360,Client发送140长度的数据给Server,Server接收返回ACK并调整窗口为260;

    2.Client接收到ACK并调整窗口为260,然后发送180的数据给Server,Server接收后返回ACK又调整窗口为80;

    3.Client接收到ACK并调整窗口为80,然后发送80的数据给Server,Server接收后返回ACK调整窗口为0;

    TCP是双工的协议,会话的双方都可以同时接收、发送数据。TCP会话的双方都各自维护一个“发送窗口”和一个“接收窗口”

    其中各自的“接收窗口”大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。

    各自的“发送窗口”则要求取决于对端通告的“接收窗口”,要求相同

    好了,差不多就这些了,好像还有非常多没有涉及,不过相信把这些都理解好了,已经足够应付大多数的面试了。

    以后有时间再整理一个应用层协议方面的文章。

    相关文章

      网友评论

      本文标题:网络知识梳理(后台开发人员面试必备)

      本文链接:https://www.haomeiwen.com/subject/ngtjkxtx.html