TCP/IP协议
TCP/IP协议
1.什么是TCP/IP协议?
TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输,网络通信的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
2.TCP/IP协议的具体含义
从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议。实际生活当中有时也确实就是指这两种协议。然而在很多情况下,它只是利用 IP 进行通信时所必须用到的协议群的统称。具体来说,IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议。他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分。TCP/IP 一词泛指这些协议,因此,有时也称 TCP/IP 为网际协议群。
互联网进行通信时,需要相应的网络协议,TCP/IP 原本就是为使用互联网而开发制定的协议族。因此,互联网的协议就是 TCP/IP,TCP/IP 就是互联网的协议。
OSI七层模型 | TCP/IP模型 | 功能 | TCP/IP协议族 |
---|---|---|---|
应用层 | 应用层 | 提供即时通讯,文件传输,虚拟终端等 | HTTP,FTP,TFTP,DNS,SMTP,POP3 |
表示层 | 提供数据的编码和数据的加密 | ||
会话层 | 建立进程间的联系 | ||
传输层 | 传输层 | 提供进程到进程,端对端的通信 | TCP、UDP |
网络层 | 网络层 | 实现数据包的路由 | IP ICMP IGMP BGP RIP OSPF |
数据链路层 | 数据链路层 | 提供差错校验 | ARP RARP PPP |
物理层 | 承载上层数据 |
3.网络数据格式
网络中传输的数据包含两部分,一部分为协议头,存储了该层必要的控制信息,而且每一层都会将上一层的控制信息和上一层的数据部分作为本层的数据部分
4.以太网协议
以太网(英语:Ethernet)是一种计算机局域网技术。IEEE组织的IEEE 802.3标准制定了以太网的技术标准,它规定了包括物理层的连线、电子信号和介质访问控制的内容。以太网是目前应用最普遍的局域网技术,取代了其他局域网标准如令牌环、FDDI和ARCNET。
以太网的标准拓扑结构为总线型拓扑,但目前的快速以太网(100BASE-T、1000BASE-T标准)为了减少冲突,将能提高的网络速度和使用效率最大化,使用交换机(Switch hub)来进行网络连接和组织。如此一来,以太网的拓扑结构就成了星型;但在逻辑上,以太网仍然使用总线型拓扑和CSMA/CD(Carrier Sense Multiple Access/Collision Detection,即载波多重访问/碰撞侦测)的总线技术。
1.以太网包头
1.目标MAC地址(48bit)
数据帧目标主机的MAC地址
2.源MAC地址(48bit)
数据帧发送端主机的MAC地址
3.上层协议类型(16bit)
用于表示上层的协议如(0806表示arp,0800表示ip)
4.FCS帧校验序列(32bit)
数据帧的校验码,用于校验数据帧的完整性
5.IP协议
网际协议(英语:Internet Protocol,缩写:IP),又称互联网协议,是用于分组交换数据网络的协议。
IP是在TCP/IP协议族中网络层的主要协议,任务仅仅是根据源主机和目的主机的地址来传送数据。为此目的,IP定义了寻址方法和数据报的封装结构。第一个架构的主要版本为IPv4,目前仍然是广泛使用的互联网协议,尽管世界各地正在积极部署IPv6。
1.IP包头
1.版本号(4bit)
0100为IPV4,0110为IPV6
2.首部长度(4bit)
指明整个ip包头的长度,ip包头的长度介于20-60个字节之间,因此此字段的单位为四字节
3.服务类型(8bit)
服务器类型(TOS)字段,其中前3个bit表示优先权(现在已经忽略该字段),随后的4个bit表示服务类型,按顺序分别表示为最小时延、最大吞吐量、最高可靠性、最小费用四种。这个4个bit中最多只能有1个bit置位,如果全是0则表示一般服务。最有1个bit为未用位,必须置0
4.总长度(16bit)
表示整个ip包的总字节数
5.标识符(16bit)
16bit的标识字段唯一的标识主机发送的每一份数据报,由于数据在发送时会进行分片,到达目标主机后会将数据包分片进行重组,此标识符用于区别该分片属于哪个数据包,由主机生成具有唯一性。通常每发送一份报文该值加1。该值在数据包分片时,会复制到每一个片中。所以在重组分片包的时候会观察该值,把该值相同的分片收集到一起重组,后面会继续讨论分片。
6.标志位(3bit)
3bit的标识字段每一位都有特定的含义,该字段主要用来分片和重组。第1个bit为保留位(Reserved Bit),一般置位0。第2个bit为不分片位(Don’t Fragment),该位在置1时表示不分片。第3个bit为更多片位(More Fragment),该位表示后面是否还有更多的分片,置位1时表示后面还有,所以除了最后一片报文,其他分片报文该位全部置1。
7.片偏移(13bit)
用于表明次数据包首部偏移数据包真正首部多少个字节,假如发送一个原始数据包1461个byte,那么第一个数据包分片为0,第二个数据包分片为1460
8.ttl值(8bit)
用于表示最多经过的路由器的数量,防止数据包在互联网上一直转发,消耗网络资源,ttl没经过一个路由器就会减1,当ttl减小到0时路由器就会将数据包丢弃,并向源主机回应一个icmp报文,表示ttl超时
9.协议号(8bit)
用于表示上层的协议如
十进制 十六进制 关键字 协议 引用 0 0x06 TCP 传输控制协议(TCP) RFC 793 1 0x01 ICMP 互联网控制消息协议(ICMP) RFC 792 17 0x11 UDP 用户数据报协议(UDP) RFC 768 10.首部校验和(16bit)
用于校验ip首部是否正确,不对ip包的数据部分进行校验
计算方法:首先把首部中的该字段全部置0,然后对首部中的每个16bit进行反码求和,得到的值就是该字段的值,填入后。将该数据包发给接收端后,接收端将进行相同的操作,对每个16bit进行反码求和(此时首部校验和字段为非0字段),所以计算后的值若为全1表示正确,否则表示收到的数据包不正确,动作为丢弃。
11.源IP地址
发送端的ip地址
12.目标IP地址
接受方的ip地址
13.可选项
2.IP地址
IP地址标识着网络中一个系统的位置。每个IP地址都是由两部分组成:网络号和主机号。网络号标识一个物理的网络,同一个网络上所有的主机需要同一个网络号,该号在整个互联网是唯一的;主机号是网络中的一个工作端、服务器、路由器其他TCP/IP主机。对于一个网络号来说主机号是唯一的。每个TCP/IP主机由一个逻辑IP地址确定。
IP地址有两种表示方法:二进制表示、点分十进制表示。
每个IP地址为4个字节,由4个8位域组成,称之为8位体。
3.IP地址划分
IP地址划分为5类
- 1.A类地址( 0.0.0.0 - 127.255.255.255 )以”0”头,网络段长度为8位,其中可变部分的长度为7位;主机段长度为24位。7位的可变网络段可识别2^7=128 (0~127)个网络,其中0和127另有用途,故只有126个可用的A类网络地址。另外,主机位全”0”代表网络本身,全”1”代表网内广播,因此一个A类网络地址可识别的可分配地址有 2^24-2 个。
- 2.B类地址( 128.0.0.0 - 191.255.255.255 )以”10”开头,网络段长度为16位,可变部分的长度为14位;主机段长度为16位。14位的可变网络段可以识别的网络数为 2^14 个。另外,主机位全”0”与全”1”功能同A类地址,因此一个B类网络可以分配地址有 2^16-2 个。
- 3.C类地址( 192.0.0.0 - 223.255.255.255 )以”110”开头,网络段长度为24位,其中可变部分的长度为21位;主机段长度为8位。21位的可变网络段可以识别的网络数为 2^21 个。可分配的主机地址是 2^8-2 个。
- 4.D类地址( 224.0.0.0 - 239.255.255.255 )为组播地址,使用”1110”开头,不分网络段和主机段,有 2^28 个组播地址。用于标识预先定义的一组主机。主机使用组播通信时,可以将组播数据报一次性发送给所有同组的主机。
- 5.E类地址( 240.0.0.0 - 255.255.255.255 )是保留地址,用于研究使用。以”1111”开头,不区分网络段和主机段,其中32位全1代表本网络内广播,因此E类地址共有 2^28-1 个。
ip地址又有私有ip地址(主要为了解决ip地址不够用的问题)和特殊ip地址
私有IP地址
A类私有ip地址(10.0.0.0/8)
B类私有ip地址(172.16.0.0/12)
C类私有ip地址(192.168.0.0/16)
特殊ip地址
127.0.0.0/8,本地回环地址,用于表示本机,常用于测试
169.254.0.0/16,主要用于DHCP服务器出问题时本地局域网计算机可以继续进行通讯
6.TCP/UDP协议
1.TCP协议
传输控制协议(英语:Transmission Control Protocol,缩写:TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。
TCP包头(20byte~60byte)
1.源端口(16bit)
发送端的端口号
2.目的端口(16bit)
目标端的端口号
3.序号(32bit)
顺序号,4个字节,用来标识从 TCP 源端向 TCP 目的端发送的数据字节流,它表示在这个报文段中的第一个数据字节的顺序号。如果将字节流看作在两个应用程序间的单向流动,则 TCP 用顺序号对每个字节进行计数。序号是 32bit 的无符号数,序号到达 (2^32) - 1 后又从 0 开始。当建立一个新的连接时, SYN 标志变 1 ,顺序号字段包含由这个主机选择的该连接的初始顺序号 ISN ( Initial Sequence Number )
4.确认号(32bit)
确认号,4个字节,包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当是上次已成功收到数据字节顺序号加 1 。只有 ACK 标志为 1 时确认序号字段才有效
5.数据偏移量(4bit)
包头长度(单位为4字节)
6.保留位(6bit)
保留区域,6位,保留给将来使用,目前必须置为 0
7.控制位(6bit)
URG,为1表示紧急指针值有效,反之无效
ACK,为1表示确认号有效
PSH,为1表示带有PUSH标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
RST,用于复位,表示出现了主机崩溃或者错误连接
SYN,同步序号,为1表示连接请求,用于建立连接和使顺序号同步
FIN,用于释放连接
8.窗口大小(16bit)
窗口大小,2个字节,表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小。窗口大小是一个 16bit 字段,因而窗口大小最大为 65535(2^16 - 1)
9.校验和(16bit)
校验和,2个字节,对整个的 TCP 报文段(包括 TCP 头部和 TCP 数据),以 16 位字进行计算所得。这是一个强制性的字段,要求由发送端计算和存储,并由接收端进行验证
10.紧急指针(16bit)
紧急指针,2个字节,是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。 只有当URG 标志置 1 时紧急指针才有效
11.可选项
TCP三次握手(重点)
1.Client将tcp中标志位SYN置为1,并初始化一个序列号x,用于客户端到服务端的会话,发送给服务端请求连接,此时客户端进入SYN_SEND状态
2.Server收到Client发来的请求连接报文后,会将ACK置为1,并将ack置为x+1,并初始化一个序列号y,用于以后服务端到客户端的会话表示接受连接(客户端到服务端),并将SYN置为1请求和客户端连接(服务端到客户端),此时Server进入SYN_RECV状态
3.Client收到报文后,客户端到服务端完成连接(Client进入到ESTABLISHED状态),并将ACK置为1表示接受连接(服务端到客户端),服务端收到后,服务端到客户端也完成连接,3次握手完成,此时Client和Server都进入ESTABLISHED状态
sequenceDiagram
Client->>+Server:SYN=1,seq=x
Server->>+Client:SYN=1,seq=y,ack=x+1,ACK=1
Client->>+Server:ACK=1,ack=y+1
TCP四次挥手(重点)
Client或Server均可发起断开连接,这里以客户端发起释放连接为例
1.Client将标志位FIN置为1,并将序列号seq=u(假设此时序列号为u)发送给Server,此时Client进入FIN_WAIT-1状态
2.Server收到报文后,将ACK标志位置为1,将ack置为u+1发送给Client,表示Server已经接受到Client发来的断开连接请求,Client收到该报文后会进入FIN_WAIT-2状态,此时TCP进入到半连接状态,Client到Server的连接释放,此时Server进入CLOSE-WAIT,此时Server将剩下要发完的数据依次全部发送给Client
3.Server将剩余要发送完的数据发送完成后,将FIN标志为置为1,ACK置为1,发送给Client,表示释放连接(服务端到客户端),
4.Client收到该报文后,将标志位ACK置为1,表示接受释放连接,此时Server到客户端的连接释放,TCP4次挥手完成
sequenceDiagram
Client->>+Server:FIN=1,seq=u
Server->>+Client:ACK=1,ack=u+1,seq=v
Server-->>+Client:DATA
Server->>+Client:FIN=1,ACK=1,seq=w,ack=u+1
Client->>+Server:ACK=1,ack=w+1,seq=u+1
tcp窗口控制和重发机制
首先,先考虑ACK未能发送到发送端主机的情况,在窗口一定程度较大时,即使有少部分的确认应答丢失也不会进行数据重发,因为可以通过下一个ACK进行确认
比如说,你发送1-100,101-200,201-300三个数据段,但是接收端主机的3个对应ACK前两个丢失了,只有201-300的到达,这将会刷新接收端的序列号从而不影响数据传输
高速重发控制
如果接收端接收到一个自己一个接收的序号以外的数据时,会针对当前为止收到的数据返回ACK数据包,如果接收端连续三次接受到了三个确认号一样的tcp报文,则表明有数据包丢失了,则进入重发机制,这个过程中几乎不会影响数据交互(因为即使接收端主机收到的序列号并不连续,也不会将数据丢弃而是暂时保存至缓冲区),这种机制比超时重发机制更有效,因此也称为高速重发机制。
流量控制
在tcp包头中有一个字段专门用来表明当前主机的窗口大小(即发送端主机不需要接收端发来的确认包就可以发送的最大字节数),这个字段一般会根据实时的网络情况进行自动调整,这个字段越大表明网络吞吐量更大,如果接收端缓冲区面临数据溢出时,窗口大小就会变为一个更小的值,如果,数据溢出,但是过了发送端的重发超时时间还未收到窗口更新的通知,发送端将会发送一个窗口探测的包
拥塞控制
有了TCP的窗口控制,收发主机之间不再以一个数据段为单位发送ACK,也能连续发送大量数据包
计算机网络都处于一个共享的环境。因此也有可能会因为其他主机之间的通信使网络变得拥堵,在网络出现拥堵的时候,如果发送一个较大量的数据,极有可能导致整个网络瘫痪
因此,TCP在通信一开始的时候会通过一个叫做慢启动的算法得出的数值,对收发数据量进行控制
首先,为了在发送端调节所要发送数据的量,定义了一个叫做“拥塞窗口”的概念。于是在慢启动的时候,将这个拥塞窗口的大小设置为1个数据段(1MSS),之后每收到,1次ACK,拥塞窗口的值就加1,在发送数据时,将拥塞窗口的大小与接收端主机通知的窗口大小进行比较,选择较小的值,并且发送比其还要小的数据量
随着包的每次往返,拥塞窗口也会以1、2、4等指数函数的增长,拥堵状况剧烈还是可能导致网络拥塞的发生。为了防止这些,引入了慢启动阀值的概念,只要拥塞窗口的值超出了这个阀值,在每一次收到ACK时,只允许以一种相对缓慢的方式放大拥塞窗口(MSS字节数*MSS字节数/拥塞窗口大小)
TCP的通信开始时,并没有设置相应的慢启动阀值。而是在超时重发时,才会设置为当时拥塞窗口一半的大小
当重复ACK而触发高速重发时,慢启动阀值会设置为当时窗口大小(实际已发送但未收到ACK的数据量)一半的大小(而当时窗口大小会重置为慢启动阀值+3MSS)
TCP拥塞控制算法
因为实际的网络环境是瞬息万变的,因此并没有那个算法适用与任何场景,因此在实际的生产环境下应该要对实际的需求和网络环境配置其合适的tcp拥塞控制算法,以达到最佳效果。传统的tcp拥塞控制算法分为以下两类
- 基于丢包策略的传统拥塞控制算法
- 基于延时策略的传统拥塞控制算法
TCP建立连接为什么要三次握手?
三次握手的目的是建立可靠的通信信道,而可靠的通信信道最基础的就是发送者和接受者发送接受都正常,即三次握手最主要的目的就是确认客户端和服务端发送和接受都是正常的,
第一次握手,客户端发送出建立连接报文后,自己什么都确认不了,但是服务端一旦接受到客户端发来的申请建立连接报文后,就可以确认客户端发送正常,自己接受正常
第二次握手,服务端发送确认建立连接报文后,客户端一旦接受到了就可以确认,客户端可以确认自己发送接受正常,对方发送和接受都正常
第三次握手,客户端发送出确认连接报文后,服务端一旦接收到,就可以确认自己发送接受正常,对方发送和接受都正常,
至此,客户端和服务端都能确认对方和自己发送和接收数据都是正常的。
TCP断开连接为什么要进行四次挥手?
TCP断开连接过程中的四次挥手主要就是为了双方都能确认对方都没有数据发送了。
由于 TCP 的半关闭(half-close)特性,TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
通俗的来说,两次握手就可以释放一端到另一端的 TCP 连接,完全释放连接一共需要四次握手
tcp三次握手可以携带数据吗?
第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手绝对不可以携带数据。
假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据,然后疯狂重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
为什么第二次挥手完成之后客户端到服务端的连接已经释放了,第四次挥手仍然能够发送ACK报文给服务端?
客户端到服务端连接释放后,只是服务端不在接受来自客户端发送报文的应用数据,而ACK是放在TCP头中的,因此这和客户端到服务端连接释放,但是客户端仍然能够发送ACK报文给服务端并不冲突
为什么不能用两次握手进行连接?
答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
为什么TCP客户端最后还要发送一次确认呢?
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
2.UDP协议
UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留UDP 消息的状态。因此,UDP有时被称为不可靠的数据报协议。如果需要传输可靠性,则必须在用户应用程序中实现。
UDP使用具有最小协议机制的简单无连接通信模型。UDP提供数据完整性的校验和,以及用于在数据报的源和目标寻址不同函数的端口号。它没有握手对话,因此将用户的程序暴露在底层网络的任何不可靠的方面。如果在网络接口级别需要纠错功能,应用程序可以使用为此目的设计的传输控制协议(TCP)。
UDP包头
1.源端口号(16bit)
发送端的端口号
2.目标端口号(16bit)
目的端的端口号
3.总长度(16bit)
数据包的总长度
4.校验和(16bit)
数据包的校验和
UDP的特点
1.UDP是无连接的,即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
2.UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
3.UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文。
4.UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。很多的实时应用(如IP电话、实时视频会议等)要去源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太多的时延。UDP正好符合这种要求。
5.UDP支持一对一、一对多、多对一和多对多的交互通信。
6.UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
参考:
维基百科
https://segmentfault.com/a/1190000039165592
https://zhuanlan.zhihu.com/p/53374516
https://blog.csdn.net/qq_30549833/article/details/60139328
https://blog.51cto.com/u_13854765/2163296
https://blog.csdn.net/why_still_confused/article/details/51658930