TCP/IP协议
TCP/IP是一个协议簇,TCP和IP是其中有代表性的协议,用以实现网络间的信息传输。
下面依次从下到上来对各层进行介绍。
1 网络接口层(数据链路层)
该层定义了主机的身份,即MAC地址。 数据包从一张网卡发送到另一张网卡,每张网卡有自己的MAC地址;在以太网中,以广播的方式把数据包发送给子网内所有的主机,子网内的主机收到报文后,读取这个报文中目标的MAC地址,只有与本机相同才会处理,否则就丢弃。
2 网络层
该层定义了IP地址,明确了主机所在的网段。
2.1 IP协议
IP协议使得可以区分两台主机是否属于同一网络;IP地址分为两段即 网络地址(地址+掩码 得到的地址) 和 主机地址,网络地址相同的归属同一个网络。
2.2 ARP协议
地址解析协议,根据IP地址获取到MAC地址。 具体过程如下: ARP发送一个请求数据包(包含目标主机IP地址),该包经数据链路层封装为以太网数据包在子网内广播;子网内的每一台主机收到该包,比较IP地址是否为本机的,如果是则返回自己所在机器的MAC地址,这样就确认了目标主机的MAC地址。源主机还会将目标主机的IP地址与MAC地址的对应关系在本机的ARP缓存中保留一段时间,下次发包可直接通过缓存找到对应目标主机的MAC地址。
2.2 路由协议
通过IP地址可以知道两台主机是否在同一个子网内。 如果在同一个子网内,则直接通过ARP协议查找到目标主机的MAC地址,然后通过MAC地址广播到目标主机。 如果不在同一个子网内,以太网包会先发给本子网的网关(各子网间的桥梁)进行路由,经过多次网关转发,发送到目标子网,此时再通过ARP找到目标主机。
3 传输层
该层定义了端口,用于标识应用身份,实现端口到端口的通信。 MAC地址为主机身份;IP地址可确定主机所在网络,与目标主机是否在同一子网;有了IP和MAC地址可以使数据包从一台主机发送到另一台主机。然而实际上,数据包是主机上某个应用发出,再由目标主机的某个应用接收。但是一台主机有多个不同的应用,数据到达目标主机后如何分发到正确的应用呢?传输层就是给每个应用标识身份。
3.1 UDP (User Data Protocol)
典型应用为:DHCP、DNS、TFTP
该协议定义了端口,主机上的每种应用都需要指定一个唯一的端口号,并且在网络传输时加上该端口号,目标主机收到该数据包后,就可以根据端口号找到应用了。 UDP提供了一种简单的面向数据报文的传输层协议,不提供可靠性,它只负责把应用层的数据发送出去,但不能保证其能到达目的地。由于不需要在主机间建立连接,也没有重发机制,所以速度很快。
UDP报文头长度位16位,所以UDP报文最大长度位64K。 UDP是面向报文的,不会分包、也不会合并包,只会将应用层的报文原样发出,如果报文超长,只能在应用层分包,组包。UDP没有粘包问题,对端要么没收到,要么收到的是一个完整的UDP包。
3.2 TCP (Transmission Control Protocol)
典型的应用为:HTTP、FTP、Telnet
相比UDP而言,TCP更容易收到攻击。 该协议提供的是面向连接的可靠的字节流服务,在两主机传送数据前,必须先在双方之间建立一个TCP链接;并且提供超时重发,丢弃重复数据、校验数据、流量控制等,保证数据能从一端传送到另一端。 一般TCP的SOCKET是全双工的(既有发送缓冲区又有接受缓冲区);发送的报文太小,会先放在缓冲区,等报文差不多以后再一起发送出去;如果发送的报文太大,会拆分为多包发送出去。因此会导致服务端不是一次收到一个完整的包,需要拼接多次接收到的报文才能获得完整的报文,因此存在粘包问题。要解决该问题,需要明确两个包的边界,
有如下几种方法:
- 定长包:保证每次按固定大小取。
- 变长包:包头位置定义报文长度。
- 变长包:包之间使用间隔符。
TCP报文头结构如图所示:
1、端口号
1)源端口(16bit):源端口和IP地址的作用是标识报文的返回地址。
2)目的端口(16bit):端口指明接收方计算机上的应用程序接口。
TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。
2、序号(32bit)和确认号(32bit):是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。
3、数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。
4、保留(6bit):为将来定义新的用途保留,现在一般置0。
5、控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能。 1)URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。 2)ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。 3)PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。 4)RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。 5)SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。 6)FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
6、窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是一个16bit字段,因而窗口大小最大为65535。
7、校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
8、紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
9、选项和填充(32bit):最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
10、数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。
3 应用层
该层定义数据格式来解析数据报文。 在有了数据链路层、网络层、传输层,数据可以从一台主机的应用传输到另一台主机的应用,此时传输的是字节流,不能很好的被识别。应用层定义了各种与应用匹配的协议来规范数据格式。并在头中可指定应用类型,这样在接收到数据报文后,就知道用什么格式来解析应用报文。
4 TCP/IP 三次握手和四次挥手
第一次握手:客户端发送syn包(syn=x)的数据包到服务器,并进入SYN_SEND状态,等待服务器确认; 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP连接都将被一直保持下去。
终止连接协议(四次挥手) 第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接受数据。 第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号, SYN 和 FIN 都有seq序号)。 第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。 第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1完成四次挥手。
ps:本文主要用于自我学习内容的整理,用于备忘。