| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> TCP/IP -> 正文阅读 |
|
[网络协议]TCP/IP |
目录 链路层TCP/IP支持多种不同的数据链路协议,这取决于网络所使用的硬件,如以太网、令牌环网、FDDI、RS-232串行线路等,当今TCP/IP采用的主要局网技术是以太网。 ? 以太网的帧结构 ? ? 帧数据的发送方式以“广播”的方式在子网络内的主机之间传输。广播就是它不是把帧数据准确送到接收方,而是向本网络内所有计算机发送,每台计算机根据收到的帧数据的标头的MAC地址判断自己是否为接收方。 ? 一个帧首部的发送者和接收者信息由MAC地址确定,MAC地址在每台主机的网卡上,是唯一的。 ? 最大传输单元MTU: 数据链路层中的不同协议对帧的数据部分长度都有一个限制,不同协议的MTU值不同。 常用的以太网为1500个字节,MTU主要是为了限制一次传输的最大IP数据报的值,如果IP层有一个数据报要传,而且数据产度比数据链路层的MTU大,则就需要将IP数据报进行分片,使每一片都小于MTU。 网络层IP协议? ? 前20字节和紧接其后的选项部分是IP数据报的首部,前20个字节是固定的,选项最多40字节,整个IP首部长度在20-60之间。 ? 因为首部字节数那里是16位,16位能表达的最大长度为2^16=65535字节,即IP数据包最大总长度包含首部和数据为65535字节。但是实际上当IP数据包的长度大于MTU时,就会进行IP分片,把很长的IP数据包分成不同的部分加在帧数据中。 ? IP协议的分片: IP数据报在长度超过MTU时会发生分片,在接收端再将分片重组,通常只有UDP协议加了IP首部之后的IP数据包会发生分片。分片传输的IP数据报不一定按序到达,但IP首部中的信息能让这些数据报片按序组装。IP数据报的分片与重组是在网络层进完成的。 ? IP协议规定了该网络地址的规则,作用是为每个计算机一个网络地址,让我们区分不同MAC地址的计算机是否在同一个子网络中。 规定网络地址/IP地址由4组8个的二进制位构成,我们通常不用它的二进制形式,而是用每个组的十进制表示,从0.0.0.0一直到255.255.255.255。IP地址一部分代表不同子网络,一部分代表不同主机,这两部分的位数不是定死的,不能直接从IP地址上得到它的子网络和主机,要用子网掩码区分。 ? 子网掩码是表示子网络特征的一个参数,在形式上等同于IP地址,但是它的网络部分全部为1,主机部分全部为0,写成十进制举个例子为255.255.255.0。 ? 判断是否是同一子网络用IP地址和子网掩码与运算。 ? ? ARP协议 ARP协议只用在局域网中。通过IP地址可以得到对方主机是否在同一子网络,如果在同一子网络,用ARP协议根据目标主机的IP地址得到目标主机的MAC地址,进而通过以太网协议进行广播传输。 ? ? ARP协议原理: 局域网中的每个主机都有一个ARP缓存,它保存了最近发起的IP地址到MAC地址的映射记录,当该主机要向局域网中的某一主机发送数据时,它会先从自己的缓存中查找映射,看是否存在目标IP地址, 如果找到,就通过映射找到它的MAC地址,从而发送过去 如果没有找到该目的IP地址,它就向该局域网内发送一个广播,广播中包含自己的IP地址、MAC地址和目的主机的IP地址,局域网内的所有主机都会收到该广播,但只有目的IP地址的主机会做出回应,并把自己的MAC地址发送给源主机,源主机收到后,在自己的ARP缓存中增加上该映射,并根据发来的MAC地址将数据发送给目的主机。 传输层UDP与TCPUDP协议用户数据报协议 UDP是一个简单的面向数据报的传输层协议:进程的每个输出操作都会产生一个UDP数据包,并组装成一份待发送的IP数据包。首部一共8个字节。 ? 特点: UDP是不可靠的协议,没有超时和重传功能。当UDP数据封装到IP数据报传输时,如果丢失,会发送一个ICMP差错报文给源主机;由于有最大长度限制,大于这个限制的数据报会被截断,从而发生数据丢失,且不会有任何数据丢失的通知;如果UDP数据报的发送端没打开UDP校验和,而接收端计算校验和有差错,那么UDP数据报将会被丢掉,不会发送ICMP差错报文。 ? UDP数据报的长度 理论上是总长度是IP数据包数据内容的长度65507,但是UDP有最大长度限制,通常会比这个小。 ? ? TCP协议传输控制协议 TCP提供了一种可靠的、面向连接、面向字节流的数据传输服务,它会在两个使用TCP的应用之间建立一个TCP连接,在该连接上进行数据的传输。 ? TCP缓存 发送方和接收方tcp协议内部维护一个缓存区用来存放字节流,缓存区分发送缓存和接收缓存,分别给字节编号。 发送缓存:任何时候在其发送缓存内的数据都可以分为4类,“已经发送并得到对端ACK的”,“已经发送但还未收到对端ACK的”,“未发送但允许发送”,“未发送但不允许发送”。 接收缓存:在某一时刻在它的接收缓存内存在2种。“已接收且已回复但未被读取”,“已接收但未确认”。 ? TCP数据报 TCP首部长度在20-60字节之间。 ? 序列号: 首部中的序号字段指本报文段所发送的数据的第一个字节在缓冲区的序号,序号的范围为[0,4284967296]。由于TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,序号是循环使用的,当序号增加到最大值时,下一个序号就又回到了0。 ? 确认号: 当ACK标志位为1时有效,表示期望收到的下一个报文段的第一个数据字节的序号。确认号为N,则表明到序号N-1为止的所有数据字节都已经被正确地接收到了。 ? 头部长度: ? 保留位:必须为0 ? 六个控制位说明报文段的性质: ACK: TCP规定,在连接建立后所有的传送报文段都必须把ACK置1。 SYN: 用来发起一个连接。当SYN=1而ACK=0时,表明这是一个连接请求报文段,若对方同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。 FIN: 用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放连接。 RST: 表示复位,用来异常的关闭连接 ? 窗口尺寸: 接收方让发送方下次发送报文段时设置的发送窗口的大小。 ? 校验和: 校验的字段范围包括首部和数据这两部分。 ? 选项与填充: 最常见的可选字段是最大分段大小MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段中指明这个选项。 ? ? TCP分段 最大分段大小MSS MSS是TCP里的一个概念。MSS是TCP数据包每次能够传输的最大数据分段,MSS的值一般为MTU值减去两个首部大小(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)。 ? TCP报文段数据的长度大于MSS时,要进行分段传输。TCP协议在建立连接的时候通常要协商双方的MSS值,每一方都有用于通告它期望接收的MSS选项(MSS选项只出现在SYN报文段中,即TCP三次握手的前两次)。所以如果用链路层以太网,MSS的值往往为1460。 ? 由于一直有MSS<=MTU,很明显,分段后的每一段TCP报文段再加上IP首部后的长度不可能超过MTU,因此也就不需要在网络层进行IP分片了。因此TCP报文段很少会发生IP分片的情况。 再来看UDP数据报,由于UDP数据报不会自己进行分段,因此当长度超过了MTU时,会在网络层进行IP分片。同样,ICMP(在网络层中)同样会出现分片情况。 ? ? 另外,IP数据报分片后,只有第一片带有UDP首部或ICMP首部,其余的分片只有IP头部,到了端点后根据IP头部中的信息再网络层进行重组。而TCP报文段的每个分段中都有TCP首部,到了端点后根据TCP首部的信息在传输层进行重组。 ? ? TCP数据报长度 TCP首部中没有对TCP最长报文段的限制,TCP有流量控制机制确定每个报文段的大小,当然在超过MSS值时会产生分段。 ? ACK确认 当TCP接收端收到发送端发来的TCP报文段时,将由TCP直接发送一个ack确认信息,确认信息只有头部没有数据,不占用序列号。称为延迟ack确认,三种情况 1、这时最普遍的情况,刚接收数据就发确认不能利用这点时间让上层应用消化掉接受窗口的数据,而推迟会让自己的接受窗口变大,这个确认信息通常会推迟几分之一秒。 2、如果接收方有数据要发送,那么就会在发送数据的TCP数据包里,带上ACK信息,也叫捎带ACK,TCP握手用到了。这样做,可以避免大量的ACK以一个单独的TCP包发送,减少了网络流量。 ? 3、利用滑动窗口机制,多次发送报文,而确认时只要确认最终的报文就可以了,可以降低网络流量。 ? 还有立即确认的情况, 如果采用快重传算法,收到数据包的顺序不一致,遇到乱序报文就不能等待接收失序的数据包,就要立刻对失序之前的数据包进行重复确认,重复三次发送端重新传输整个数据包。 ? 超时重传 当TCP发出一个报文段后,它会启动一个定时器,等待目的端发确认收到这个报文段,当来自TCP报文段的某一段(在IP数据报的某一片中)丢失,接收端会丢弃整个IP数据包不会发送确认信息,TCP在超时后会重发整个TCP报文段。 TCP的连接和释放TCP的三次握手 服务端的TCP进程先创建传输控制块TCB,准备接受客户端进程的连接请求,然后服务端进程处于LISTEN状态,等待客户端的连接请求,如有,则作出响应。服务器先从最初的CLOSED到LISTEN ? ??? 1、客户端的TCP进程也首先创建传输控制模块TCB,然后向服务端发出连接请求报文段,该报文段首部中的SYN=1,同时选择一个初始序号seq=i。TCP规定,SYN=1的报文段不能携带数据,但要消耗掉一个序号。。客户端从CLOSED到SYN-SENT状态 ? ??? 2、服务端收到客户端发来的请求报文后,如果同意建立连接,则向客户端发送确认。确认报文中的SYN=1,ACK=1,确认号ack=i+1,同时为自己选择一个初始序号seq=j。同样该报文段也是SYN=1的报文段,不能携带数据,但同样要消耗掉一个序号。这时,TCP服务端进入SYN—RCVD(同步收到)状态,这是TCP连接的第二次握手。服务器端从LISTEN到SYN-RCVD状态 ? ??? 3、TCP客户端进程收到服务端进程的确认后,还要向服务端给出确认。确认报文段的ACK=1,确认号ack=j+1,而自己的序号为seq=i+1。TCP的标准规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号,因此,如果不携带数据,则下一个报文段的序号仍为seq=i+1。这时,TCP连接已经建立,客户端进入ESTABLISHED(已建立连接)状态。????? 客户端从SYN-SENT到ESTABLISHED状态,服务器端从SYN-RCVD到ESTABLISHED状态 ? ? 三次握手干了什么?测试双方连接的可靠性,对滑动窗口进行协商,对MSS大小进行协商,对加密套件进行协商。 ? 携带数据? 第一次第二次握手不可以携带数据,第三次握手可以。 第一次不可以是因为防止大量携带数据的SYN报文发送到服务器造成服务器过载。 ? TCP的四次挥手 ? 数据传输结束后,通信的双方都可以释放连接,并停止发送数据。假设现在客户端和服务端都处于ESTABLISHED状态。 ? ??? 1、客户端A的TCP进程先向服务端发出连接释放报文段。释放连接报文段中FIN=1,ACK=1,序号为seq=u,该序号等于前面已经传送过去的数据的最后一个字节的序号加1。这时,A进入FIN—WAIT-1(终止等待1)状态,等待B的确认。TCP规定,FIN报文段即使不携带数据,也要消耗掉一个序号。这是TCP连接释放的第一次挥手。客户端状态ESTABLISHED到FIN—WAIT-1 ? ??? 2、B收到连接释放报文段后即发出确认释放连接的报文段,该报文段中,ACK=1,确认号为ack=u+1,其自己的序号为v,该序号等于B前面已经传送过的数据的最后一个字节的序号加1。然后B进入CLOSE—WAIT(关闭等待)状态,此时TCP服务器进程应该通知上层的应用进程,因而A到B这个方向的连接就释放了,这时TCP处于半关闭状态,即A已经没有数据要发了,但B若发送数据,A仍要接受,也就是说从B到A这个方向的连接并没有关闭,这个状态可能会持续一些时间。这是TCP连接释放的第二次挥手。客户端状态FIN—WAIT-1到FIN—WAIT-2,服务端状态ESTABLISHED到CLOSE—WAIT ? ??? 3、A收到B的确认后,就进入了FIN—WAIT(终止等待2)状态,等待B发出连接释放报文段,如果B已经没有要向A发送的数据了,其应用进程就通知TCP释放连接。这时B发出的链接释放报文段中,FIN=1,ACK=1,确认号还必须重复上次已发送过的确认号,即ack=u+1,序号seq=w,因为在半关闭状态B可能又发送了一些数据,因此该序号为半关闭状态发送的数据的最后一个字节的序号加1。这时B进入LAST—ACK(最后确认)状态,等待A的确认,这是TCP连接的第三次挥手。服务端状态CLOSE—WAIT到LAST—ACK ? ??? 4、A收到B的连接释放请求后,必须对此发出确认。确认报文段中,ACK=1,确认号ack=w+1,而自己的序号seq=u+1,而后进入TIME—WAIT(时间等待)状态。这时候,TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态,时间MSL叫做最长报文寿命,RFC建议设为2分钟,因此从A进入TIME—WAIT状态后,要经过4分钟才能进入到CLOSED状态,而B只要收到了A的确认后,就进入了CLOSED状态。二者都进入CLOSED状态后,连接就完全释放了,这是TCP连接的第四次挥手。客户端状态FIN—WAIT-2到TIME—WAIT,服务端状态LAST—ACK到CLOSED,经过2MSL后客户端状态TIME—WAIT到CLOSED。 ? 握手 1. (B) --> [SYN] --> (A) 2. (B) <-- [SYN/ACK] <--(A) 3. (B) --> [ACK] --> (A) ? 挥手 1. (B) --> ACK/FIN --> (A) 2. (B) <-- ACK <-- (A) 3. (B) <-- ACK/FIN <-- (A) 4. (B) --> ACK --> (A) 流量控制机制交互数据流和成块数据流 建立在TCP协议上的应用层协议有很多,如FTP、HTTP、Telnet等,这些协议根据传输数据的多少可以分为两类:交互数据类型和成块数据类型。 ??? 交互数据类型,如:Telnet,这类协议一般只做小流量的数据交换,比如每按下一个键,要回显一些字符。 ?? ?成块数据类型,如:FTP,这类协议需要传输的数据比较多,一般传输的数据量比较大。 ? 交互数据流流量控制机制 捎带ACK 意思是当接收端接收到TCP报文段后,并不立即发送ACK报文,而是等上一段时间,如果这段时间里该主机有数据要发送到远程主机,就将该数据捎带上ACK一起发送过去,把2和3合并。很明显,这样可以减少传输开销。为了防止产生超时重传,绝大多数情况下,这个等待时间为200ms,超过了200ms,如果没有数据要一起发送,就直接发送ACK报文。 作用能减少流量浪费。 ? ?Nagle算法 即使发送一个字节,也需要加入 tcp 头和 ip 头,也就是总字节数会使用 41 bytes,非常不经济。因此为了提高网络利用率,tcp 希望尽可能发送足够大的数据,这就是 Nagle 算法产生的缘由 该算法的重点是要求在TCP连接上最多只能有一个未被确认的数据报在传输。 算法的大致思路如下:应用程序把要发送的数据逐个字节地存到TCP的发送缓存,发送方把前面的一部分数据先发送出去,并把后面到达的字节继续缓存起来,当发送方收到前面字节的确认后,再把发送缓冲中的所有数据组装成一个报文段发送出去,同时继续对随后到来的数据进行缓存。只有收到前一个报文段的确认后才能继续发送下一个报文段。另外,Nagle算法还规定,当发送缓存中的数据已达到发送窗口大小的一半或已达到报文段的MSS值时,就立即发送一个报文段。 作用能减少所用的网络带宽。 ? 成块数据流流量控制机制 ? 滑动窗口是通过确认信息完成的。 滑动窗口的作用是 1、允许发送方连续发送多个报文,只要不超过窗口大小限制。 2、接收端告诉发送端自己还有多少缓冲区可以接收数据,于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。 ? 滑动窗口是缓存的一部分,滑动窗口包括接收窗口和发送窗口 ? 发送窗口: 发送窗口指发送缓存中的中间两部分“已经发送但还未收到确认”,“未发送但准备发送”。 ? 发送窗口在接收到确认报文后,根据确认报文的ack确认号的值把左端右移到对应序号,发送窗口左端右移,并根据发过来的接收窗口参数和拥塞窗口参数动态调整发送窗口大小,发送窗口右端右移。 然后发送窗口在发送报文时,两个区的分界线也右移。 ? 接收窗口: 接收窗口指ACK确认报文中的窗口参数 ? ? 流程 拥塞控制机制拥塞控制机制 拥塞窗口 cwnd ( congestion window )是客户端或者服务器维护的一个状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口和接收窗口的最小值。 ? 慢开始 当主机开始发送数据时,如果立即所大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。因此,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。 通常在刚刚开始发送报文段时,先把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送方的拥塞窗口 cwnd ,可以使分组注入到网络的速率更加合理。 1)连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。 2)每当收到一个ACK,cwnd就加1 3)每当过了一个RTT,cwnd = cwnd*2,因为每一个ack通知都让cwnd加1了,总体就是大了2倍。 4)为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量,当cwnd >= ssthresh时,就会进入“拥塞避免算法” ? 拥塞避免 为了避免增长过快导致网络拥塞,让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd整体加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。 ? 慢开始和拥塞避免组合 无论在慢开始阶段还是在拥塞避免阶段,只要发送方没有收到确认信息,那么很可能是网络出现了拥塞,致使报文段在网络中的某处被丢弃,这时就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生 拥塞的路由器有足够时间把队列中积压的分组处理完毕。 ? 快重传 发送方没有收到确认信息,那么很可能是网络出现了拥塞,致使报文段在网络中的某处被丢弃,如果用快重传算法就会要求接收方每收到一个失序的报文段后就立即对失序之前的报文发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不是进行延迟ack确认。 ? 接收方收到了M1和M2后都分别发出了确认。现在假定接收方没有收到M3但接着收到了M4。显然,接收方不能确认M4,因为M4是收到的失序报文段。根据默认的延迟确认,接收方可以什么都不做,也可以在适当时机发送一次对M2的确认。但按照快重传算法的规定,接收方应及时发送对M2的重复确认,这样做可以让 发送方及早知道报文段M3没有到达接收方。发送方接着发送了M5和M6。接收方收到这两个报文后,也还要再次发出对M2的重复确认。这样,发送方共收到了接收方的四个对M2的确认,其中后三个都是重复确认。 快重传算法还规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段M3,而不必继续等待M3设置的重传计时器到期。 ? 快恢复(目前默认在用:慢开始→拥塞避免→快重传→快恢复) 发送方进行快重传时,执行快恢复算法。 <1>. 当发送方连续收到三个重复确认,把慢开始门限ssthresh设为此时拥塞窗口值的一半。这是为了预防网络发生拥塞。请注意:接下去不执行慢开始算法。 <2>. 由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为减半后的慢开始门限ssthresh数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。 ? 快重传和快回复旨在快速地传输丢失的数据包。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 21:35:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |