TCP/IP
一、TCP/IP模型
二、数据链路层
三、网络层
- 1、IP协议
- 1.1 IP地址
- 1.2 子网
- 1.2.1 子网作用
- 1.2.2 为什么要用子网掩码
- 1.2.3 子网掩码的分类
- 1.2.4 子网掩码与IP地址的关系
- 1.2.5 为什么要划分子网
- 1.2.6 子网划分
- 1.2.7 子网掩码的计算
- 2、ARP和RARP协议
- 3、ICMP协议(Internet Control Message Protocol,网络控制报文协议)
四、ping
五、Traceroute
六、TCP/UDP
- 1、TCP和UDP的应用
- 2、什么时候用TCP?
- 3、什么时候用UDP?
七、DNS
八、TCP连接的建立和终止
- 1、三次握手
- 2、四次挥手
九、TCP流量控制
十、TCP拥塞控制
- 1、慢开始和拥塞避免
- 2、快重传和快恢复
一、TCP/IP模型
TCP/IP协议通信的过程其实就是数据入栈出栈的过程。入栈就是数据发送方每层不断的封装首部和尾部,添加一些传输的信息,保证能传输到目的地、出栈就是数据接收方每层不断的拆除首部和尾部,得到最终的传输数据。
下图是以http协议来说明:
二、数据链路层
物理层负责的是0、1比特流与物理设备电压高低、光的闪灭之间的互换。
数据链路层负责的就是将这些0、1序列划分为数据帧,然后从一个节点(主机)传输到另一个节点(主机)。
这些节点是通过MAC来唯一标识的(MAC,物理地址,一个主机有一个MAC地址)。
封装成帧:把网络层数据报加头和尾,封装成帧,帧头包括了源MAC地址和目的MAC地址;
透明传输:0比特填充、转义字符;
可靠传输:在出错率很低的链路上很少用(因为一根线连着彼此,当然不会出错),在无线链路WLAN会保证可靠传输;
差错检测(CRC,Cyclic Redundancy Check,循环冗余校验):接受者检测错误,如果发现错误,就丢弃该帧;
三、网络层
1、IP协议
IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGMP的数据都以IP数据格式传输。
要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制,这被认为是上层协议:TCP或UDP要做的事情。
1.1 IP地址
数据链路层中通过MAC地址来识别两个不同的节点,在IP层(网络层)通过IP地址来识别。
32位IP地址分为网络位和地址位,这样可以减少路由器中路由表记录的数目,有了网络地址,就可以限定拥有相同网络地址的终端都在一个范围内,那么路由表就只需要维护一条这个网络地址的方向,就可以找到相应的这些终端了。
A类地址:0.0.0.0~126.255.255.255,子网掩码:255.0.0.0(可以通过子网划分,改变子网掩码)。A类地址分配给规模特别大的网络使用。
- 127表示的是回环测试相应的地址,所以实际范围是1-126,。
- 回送地址:127.0.0.1。 也是本机地址,等效于localhost或本机IP。一般用于测试使用。例如:ping 127.0.0.1来测试本机TCP/IP是否正常。
- 私有地址范围:10.0.0.0~10.255.255.255
B类地址:128.0.0.0~191.255.255.255,默认子网掩码为:255.255.0.0。B类地址分配给一般的中型网络。
- 私有地址范围:172.16.0.0~172.31.255.255
C类地址:192.0.0.0~223.255.255.255,默认网络掩码为:255.255.255.0。C类地址分配给小型网络,如一般的局域网和校园网,它可连接的主机数量是最少的,采用把所属的用户分为若干的网段进行管理。
- 私有地址范围:192.168.0.0~192.168.255.255
D类地址(广播地址):224.0.0.0到239.255.255.255。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。
E类地址保留给将来使用:240.0.0.0到255.255.255.254。
全0和全1都不能用,主机位全0全1也不能用。这是因为这种因特网IP地址中特定的专用地址是不作分配的,主机号全为“0”。不论哪一类网络,主机号全为“0”表示指向本网,也就是网段地址,常用在路由表中,主机号全为“1”。主机号全为“1”表示广播地址,向特定的所在网上的所有主机发送数据包。
- 全零(“0.0.0.0”)地址对应于当前主机,表示该地址是本地宿主机,不能传送。
- 全“1”的IP地址(“255.255.255.255”)是当前子网的广播地址。
1.2 子网
在主机号中拿一部分作为子网号,进而把两级IP地址划分为三级IP地址。
IP地址:{< 网络号 >, < 子网号 >, < 主机号 >}
1.2.1 子网作用
子网掩码是一个应用于TCPIP网络的32位二进制值,必须结合IP地址使用。
子网掩码与32位于IP地址32位对应,方法就是如果某位是网络地址,那么子网掩码就是1,否则就是0.
子网掩码可以通过与IP地址相与计算,分理处IP地址的网络地址和主机地址,用于判断IP地址是在局域网上还是广域网上。
子网掩码一般用于将网络进一步划分为若干子网,避免主机过多而拥堵或过少而IP浪费。
1.2.2 为什么要用子网掩码
可以分离出IP地址的网络位和主机位。为什么要分离?因为两台计算机要通讯,首先要判断是否处于同一个广播域内,即网络地址是否相同。如果网络地址相同,表明接收方在本网络,那么就可以把数据报直接发送到目标主机,否则就需要通过路由网关将数据报转发送到目的地。
举例子来说:255.255.255.0
网络位有24位,主机位有8位,也就是子网的容量为2^8,第一个地址(全0,用作网段地址)后最后一个地址(全1,用作广播地址)不能用,所以主机数是2^8-2个。192.168.1.1-192.168.1.254为可用IP地址,设置这个范围内的IP地址,计算机才能能正常联网。比如一个公司里面每个部门有一个子网,互相保持机密性,那么部门之间是无法直接通信的,必须通过路由网关的把控才能通信。这样也限定了主机的数量,也提高了机密性。
1.2.3 子网掩码的分类
(1)缺省子网掩码(未划分子网)
子网掩码32位与IP地址32位对应,如果某位是网络地址,则子网掩码为1,否则为0。
A类网络缺省子网掩码:255.0.0.0
B类网络缺省子网掩码:255.255.0.0
C类网络缺省子网掩码:255.255.255.0
(2)自定义子网掩码(用于划分子网)
将一个网络划分为若干个子网,每个子网拥有不同的网络地址或子网地址。因为IP是有限的,实际上我们是将主机地址分为了两个部分:子网网络地址、子网主机地址。
未做子网划分的ip地址:网络地址 + 主机地址
做子网划分的IP地址:网络地址 + (子网网络地址 + 子网主机地址)
1.2.4 子网掩码与IP地址的关系
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。具体就是两台计算机的IP地址与子网掩码进行与计算,得到的结果相同则说明是处于同一个子网络的,可以进行直接的通讯。
IP地址与子网掩码相与,得到网络位;将子网掩码取反后再和IP地址相与,得到主机位。
1.2.5 为什么要划分子网
比如A类地址中,每个A类网络可能有很多台主机,他们处于一个广播域内。在同一个广播域内有这么多主机是不可能的,网络会因为广播通信而饱和。另一方面,IP地址资源越来越少,为实现更小的广播域,就需要进一步划分成更小的网络。划分子网后,通过使用掩码,将子网隐藏起来,使得从外部看网络没有变化,这就是子网掩码。
1.2.6 子网划分
子网划分就是借用几个主机位来充当子网的网络地址,从而将原网络划分成若干子网。
划分子网时,随着借用主机位数增多,子网数目也增多,但每个子网中可用的主机数就逐渐减少。
如C类地址,原有8位主机位,而且全0和全1不能用,所以一共有2^8-2即254个主机地址,默认子网掩码是255.255.255.0。
借用一位主机位,产生2^1-2=0个子网,每个子网有2^7个主机地址;
借用2位主机位,产生2^2-1=2个子网,每个子网有2^6个主机位;
......
1.2.7 子网掩码的计算
1、利用子网数来计算
在求子网掩码之前必须先搞清楚要划分的子网数目,以及每个子网内的所需主机数目。
- 将子网数目转化为二进制来表示
- 取得该二进制的位数,为 N
- 取得该 IP地址的类子网掩码,将其主机地址部分的的前N位置 1 即得出该IP地址划分子网的子网掩码。
如欲将C类IP地址192.168.10.0划分成4个子网:
- 4=100
- 该二进制为三位数,N = 3
- 将C类地址的子网掩码255.255.255.0的主机地址前3位置 1,得到子网掩码255.255.255.224。
2、利用主机数来计算
- 将主机数目转化为二进制来表示
- 如果主机数小于或等于254(注意去掉保留的两个IP地址),则取得该主机的二进制位数。
- 将该类IP地址的主机地址位数全部置1,然后从后向前的将N位全部置为 0,即为子网掩码值。
如欲将B类IP地址192.168.10.0划分成若干子网,每个子网内有主机25台:
1) 25=11001
2)该二进制为十位数,N = 5
3)将该B类地址的子网掩码 255.255.255.0的主机地址全部置 1,得到255.255.255.255,然后再从后向前将后5位置0,即为:11111111.11111111.11111111.11100000,即255.255.252.224。
1.3 IP协议头
八位的TTL( Time To Live)字段。这个字段规定该数据包在穿过多少个路由之后才会被抛弃。某个IP数据包每穿过一个路由器,该数据包的TTL数值就会减少1,当该数据包的TTL成为零,它就会被自动抛弃。
这个字段的最大值也就是255,也就是说一个协议包也就在路由器里面穿行255次就会被抛弃了,根据系统的不同,这个数字也不一样,一般是32或者是64。
2、ARP和RARP协议
ARP (地址解析协议,Address Resolution Protocol)是根据IP地址获取MAC地址的一种协议。
主机本来不知道这个IP对应的是哪个主机的哪个端口,当主机要送一个IP包的时候,会先查一下自己的ARP高速缓存(就是一个IP-MAC地址对应表缓存)。如果查到的IP-MAC值对不存在,那么主机向网络发送一个ARP协议广播包,这个包里面就有要查询的IP地址,接收到这份广播包的所有地址都会查询自己的IP地址,只有相同IP地址的接收到广播请求的主机或路由器,发回一个ARP应答分组,应答中包含它的IP地址和物理地址,并保存在发送ARP广播的主机的ARP缓存中。其他主机或路由器都丢弃此分组。
广播主机拿到ARP包后会更新自己的ARP缓存。发送广播的主机就会用新的ARP缓存数据准备好数据链路层的数据包发送工作。
RARP协议的工作与此相反
3、ICMP协议(Internet Control Message Protocol,网络控制报文协议)
IP协议并不是一个可靠的协议,它不保证数据被送达,那么,自然的,保证数据送达的工作应该由其他的模块来完成。其中一个重要的模块就是ICMP(网络控制报文)协议。
ICMP不是高层协议,而是IP层的协议。
当传送IP数据包发生错误。比如主机不可达,路由不可达等等,ICMP协议将会把错误信息封包,然后传送回给主机。给主机一个处理错误的机会,这也就是为什么说建立在IP层以上的协议是可能做到安全的原因。
四、ping
ping可以说是ICMP的最著名的应用,是TCP/IP协议的一部分。
利用“ping”命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障。
例如:当我们某一个网站上不去的时候。通常会ping一下这个网站。ping会回显出一些有用的信息。
ping这个单词源自声纳定位,而这个程序的作用也确实如此,它利用ICMP协议包来侦测另一个主机是否可达。原理是用类型码为0的ICMP发请求,受到请求的主机则用类型码为8的ICMP回应。
ping程序来计算间隔时间,并计算有多少个包被送达。用户就可以判断网络大致的情况。我们可以看到, ping给出来了传送的时间和TTL的数据。
五、Traceroute
Traceroute是用来侦测主机到目的主机之间所经路由情况的重要工具,也是最便利的工具。
原理就是它收到目的主机的IP地址之后,首先给IP地址发送一个TTL=1的UDP数据包,而经过的第一个路由器收到这个数据包以后,就自动把TTL减1,而TTL变成0后,路由器就把这个包给丢弃了,同时产生一个主机不可达的ICMP数据报给主机。主机收到这个数据包以后,再发一个TTL=2的UDP数据报给目的主机,然后第二个路由器就又会返回一个ICMP数据报,如此往复,知道到达目的主机,这样traceroute就拿到了所有路由器的IP。
六、TCP/UDP
TCP/UDP都是是传输层协议,但是两者具有不同的特性,同时也具有不同的应用场景。
面向报文的传输方式就是应用层交给UDP多长的报文,UDP就照样发送,也就是一次就发送一个报文。因此应用程序需要选择合适大小的报文,如果报文太长,那么IP层就需要分片,降低效率,若太短了,是IP太小。
面向字节流的传输方式就是,虽然应用程序和TCP交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流,TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。
1、TCP和UDP的应用
2、什么时候用TCP?
对网络通讯质量要求高的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。
3、什么时候用UDP?
当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。
七、DNS
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。DNS协议运行在UDP协议之上,使用端口号53。
八、TCP连接的建立和终止
1、三次握手
TCP面向连接的,无论哪一方向另一方发送数据之前,都必须要在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小信息。
第一次握手,建立连接,客户端发送连接请求报文,SYN(同步)=1,Seq(Sequence Number,序列号)=x。客户端进入SYN_SEND状态,等待服务器确认。
第二次握手,服务器收到SYN报文段。
- 服务器需要对这个报文段继续确认,设置ACK(Acknowledgement Number) = x+1;
- 同时自己还要再发送SYN请求信息,将SYN=1,Seq=y;
- 服务器端将上述所有信息放到一个报文段内(SYN+ACK+Seq报文段),一起发送给客户端,此时服务器进入SYN_SEND状态。
第三次,客户端收到服务器的SYN+ACK报文段。然后将ACK=y+1,向服务器发送ACK报文段,这个报文段发送完毕后,客户端和服务器都进人ESTABLISHED状态,完成三次握手。
为什么要三次握手?
防止已经失效的连接请求报文突然又传送到了服务端,因而产生错误。
举例:client发出的第一个连接请求报文段并没有丢失,而是在某个网络节点长时间滞留了,以至于延误到连接释放后的某个时间才到达server。本来这是一个早就失效的报文段,但是server收到这个失效的报文段,误认为是client再次发出的连接请求,于是就会向client发出确认报文段,同意建立连接,只要server发出确认,新的连接就算建立了。但是由于client并没有发出建立连接,因此不会理财server的确认报文,也不会像server发送数据,但是server却认为新的连接已经建立了,会一直等待client发来数据。这样server的很多资源就白白浪费掉了。采用三次握手就可以有效防止上述现象,在这种情况下,client不会向server发送确认报文段,server收不到确认,就知道client并没有要求建立连接。
2、四次挥手
当clilent和server通过三次握手建立了TCP连接以后,当数据传输完毕,要断开TCP连接,要进行四次挥手。
第一次分手,主机1(可以是客户端也可以是服务器端),设置Sequence Number,向主机2发送一个FIN报文段,此时主机1进入FIN_WAIT_1状态,表示主机1没有数据要发送给主机2了。
第二次分手,主机2收到了主机1的FIN报文段,向主机1发送ACK报文段,ACK = X+1,主机1进入FIN_WAIT_2状态,主机2告诉主机1,我同意你的关闭请求。此时主机2是半关闭状态,只能主机1发送给主机2,不能主机2发送给主机1。
第三次分手,当主机2不在需要主机1的报文段,主机2会向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次分手,主机1收到主机2的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态,主机2收到主机1的ACK报文段后,就关闭了连接。此时主机1等待2MSL(MaximumSegmentLifetime,最大报文存活时间)后,依然没有收到回复,则证明主机2已经正常关闭,那么主机1也关闭。
(Windows : MSL = 2 min,linux(Ubuntu, CentOs) : MSL = 60s,unix:30s)
为什么要四次分手?
TCP是面向连接的,可靠的,基于字节流的运输层通信协议。TCP是全双工的,这意味着,当主机1发出FIN报文段时,只是表示主机1没有数据要发送给主机2了,但是这个时候主机1还是可以接受主机2的数据,主机2返回ACK报文段,表示主机2知道了主机1没有数据要发送了,但是主机2还可以发送数据给主机1;当主机2发送了FIN报文段时,这个时候表示主机2也没有数据要发送了,就会告诉主机1我也没有数据要发送了,之后彼此就会中断这次TCP连接。
为什么要2MSL?
MSL:最大报文生存时间,它是任何报文段在被丢弃前在网络中存活的最长时间。
原因1:保证TCP协议的全双工连接能够可靠关闭。
如果主机1直接closed,那么由于IP协议的不可靠性或其他网络原因,导致主机2没有收到主机1最后回复的ACK。那么主机2就会在超时之后继续发送FIN,此时由于主机1已经CLOSED了,就找不到与重发的FIN对应的连接。所以,主机1不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。
原因2:保证这次连接的重复数据段从网络中消失
如果主机1直接CLOSED,然后又再向主机2发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达主机2,由于新连接和老连接的端口号是一样的,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。
九、TCP流量控制
如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是防止发送方的发送速率太快而耗尽接收方的资源,从而使接收方来不及处理。
利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
滑动窗口是类似于一个窗口,用来告诉发送端可以发送数据的大小或者说是窗口标记了接收端缓冲区的大小,窗口就是一次批量的发送多少数据。
接收端将自己可以接受的缓冲区大小放入TCP首部中的窗口大小字段( rwnd :receiver window,TCP的窗口单位是字节,不是报文段。假设每一个报文段为100字节长,而数据报文段序号的初始值设为1。大写ACK表示首部中的确认位ACK,小写ack表示确认字段的值ack。)。窗口字段越大,说明吞吐量越大,窗口大小指的是不需要接收端的应答,可以一次连续的发送数据。
发送缓冲区如果太大,就会有空间开销
接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,发送端收到这个值后,就会减慢自己的发送速度(也就是调整自己的发送窗口)。
如果接收端发现自己的缓冲区满了,就会将窗口的大小设置为0,此时发送端将不再发送数据,但是需要定期发送一个窗口探测数据段(测试报文),打听是否可以继续发送数据了,如果可以,使接收端把窗口大小告诉发送端;如果接受窗口还是0,发送端就再次刷新启动定时器,继续定期探测。
在TCP的首部中,有一个16为窗口字段,此字段就是用来存放窗口大小信息的
十、TCP拥塞控制
1、慢开始和拥塞避免
流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
发送方维持一个拥塞窗口 cwnd ( congestion window )的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
慢开始算法
当主机开始发送数据时,如果立即将大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。因此,较好的方法是 先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。
通常在刚刚开始发送报文段时,先把拥塞窗口 cwnd 设置为一个最大报文段MSS(Maximum Segment Size)的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值(即拥塞窗口长度加倍)。用这样的方法逐步增大发送方的拥塞窗口 cwnd ,可以使分组注入到网络的速率更加合理。
每经过一个传输轮次,拥塞窗口cwnd就加倍。一个传输轮次所经历的时间其实就是往返时间RTT。不过传输轮次更加强调:把拥塞窗口cwnd所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。
为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。慢开始门限ssthresh的用法如下:
-
当 cwnd < ssthresh 时,使用上述的慢开始算法。
-
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
-
当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。
拥塞避免
让拥塞窗口cwnd缓慢增大,每经过一个往返时间RTT(Round-Trip Time)就把发送方的窗口加1,,而不是加倍,这样拥塞窗口cwnd按照线性规律缓慢增长,比慢开始算法的拥塞窗口增长的慢多了。
无论是慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
2、快重传和快恢复
快重传
要求接收方每收到一个失序的报文段后就立即发出重复确认(为的就是是发送方早知道报文段有没有到达对方),而不要等到自己发送数据时才进行捎带确认。
例如接收方收到了M1和M2后都分别发出了确认。现在假定接收方没有收到M3,但接收到了M4。此时接收端及时发送对M2的重复确认,这样做可以让发送端知道报文段M3没有到达接收端。发送端接着发送M5,接收端再次发出对M2的重复确认,发送端接着发M6,接收端再次发出对M2的重复确认。也就是后面三个都是重复确认。
快重传算法还规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段M3,而不必继续等待M3设置的重传计时器到期。
由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%。
快恢复
当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限ssthresh减半。
与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为 慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。