简单的说,传输层就是将两个端口连接起来通信的介质。
网络层IP协议为非同一网络上的主机之间的精准通信提供了高效的手段。
数据链路层为同一网络下的主机之间的通信提供了基于MAC地址的身份识别手段。
物理层为数据信号在信道上传输、信号转换等提供了方案。
然而,同一台计算机内部,同一网络中,甚至是全球网络中的两台计算机的两个应用程序之间要相互通信,光靠以上三层是无法实现的,也因此引入了端口
、TCP协议
、UDP协议
。
传输层的主要任务是
- 建立端口到端口的通信。
- 通过传输层协议进行数据的传输。
端口
网络层通过IP协议,区分了子网。
以太网通过MAC地址,区分了主机。
传输层通过端口,区分了应用程序。
同一个IP下、同一个MAC地址下的同一台计算机,运行着许许多多的应用程序(进程),每一个应用程序通过端口来做唯一标识。
端口的范围为:0 - 65535,其中0 - 1023为系统占用端口,共16位, 2^16。
有了端口、IP、MAC地址之后,那么数据就可以找到传输的入口了。
传输层的传输方式包含:TCP(可靠)、UDP(不可靠)。
无论是TCP,还是UDP,目的都是为了发送IP数据包。
二者的区别主要是:有无连接、是否可靠、传输效率。
UDP,用户数据报协议。
UDP
,不需要和目标主机建立连接,直接发送数据包即可。(无连接)
无论网络问题或者目标主机问题都不管,无法保证发送的分组一定到达,只能通过ICMP
来回应异常报告,不会对分组进行超时重试、丢失重发、流量控制、乱序调整等。(不可靠)
正常情况,发出去的数据报是可以被成功接收的,并且省了建立及维护连接通道的成本。(高效)
UDP抓包情况如下:
UDP包含了:源IP地址
、目的IP地址
、协议号
、源端口
、目的端口
五元组,当一台计算机的进程收到多个进程的数据报时候,以此五元组来做区分。
TCP,传输层控制协议。
TCP
,需要先和目标主机通过三次握手建立连接,然后才能进行通信。(有连接)
无论网络问题或者目标主机问题都要管,保证发送的分组可靠到达,但不是100%。当发送分组超时了,将会重试,丢失分组了,也会重发,为了防止网络崩溃,启用了滑动窗口机制来限制发送速率,通过ack机制及包编号实现了有序性。(可靠)
由于发送数据包之前需要先建立连接,用完了还要四次挥手断开连接,再用再建立连接,如此反复,成本较大。(低效)
TCP抓包情况如下:
序列号、确认号
由于TCP是面向 字节流
的,每一个字节都会被标注一个序列号。
比如:一段数据100字节。
第1次发送50个字节,序列号 seq
为1-50,第2次序列号从51开始。
当目标主机收到数据包之后,会回复确认号ack
。
控制位
TCP包含的控制位有:URG
、RST
、PSH
、ACK
、SYN
、FIN
。
URG,紧急指针,用于标识该数据包应该被优先接收。
RST,复位,当连接断了,再继续发送包会报这个错。
PSH,推送,表示数据包被成功推送。
SYN,同步,三次握手的时候会用到。
ACK,确认,三次握手和四次挥手的时候用到,确认。
FIN,终止,四次挥手的时候用到。
窗口大小
滑动窗口,Window Size Value 随着发送端和接收端的情况动态调整。
TCP需要先经过三次握手,才能实现可靠连接。
三次握手的流程为
客户端主动打开连接,通过向服务端发送
SYN
包,并发送自己的序列号seq = x
,服务端端口监听,接收到之后,会将SYN
放到Sync Queue
半连接队列中,处理完后向客户端发送SYN + ACK
及客户端的确认号+1,ack = x + 1
,表明已经收到了SYN
连接请求,并发送自己的序列号seq = y
。客户端收到服务端发送的
SYN + ACK
后,回复一个ACK
,并将对方的确认号+1,ack = y + 1
。如果客户端没有收到服务端发送的
SYN + ACK
,那么服务端会再继续重发,直到超时或者成功。DDos
中有一种SYN Flood
洪水攻击,通过伪造大量IP端口,并发送SYN
,然后消失,导致服务端一直等不到SYN + ACK
之后的ACK
,导致稀缺的资源被占用,甚至宕机。最终,双方相互确认之后,正式建立连接,连接会在
Accept Queue
连接队列中维护,用来控制服务端最大连接数
。
三次握手的原因
可以防止已经失效的连接请求报文又被突然传到服务端,导致错误产生。
一个因为网络延迟
到达的SYN
连接请求报文被服务端接收了,没有二次确认
的话,服务端将会和客户端直接建立连接,否则客户端会将服务端回应的报文直接忽略
。
类似地,TCP需要先经过四次挥手,才能实现可靠断连。
四次挥手的流程为
客户端发送
FIN
主动关闭连接,并发送序列号seq = x
,同时可能会发送ACK
,用来确认之前接收的报文,然后进入FIN_WAIT_1
状态,等待服务端回应,并且不会再发送数据了。服务端接收到客户端的
FIN
控制指令,此时还有未发送完的数据,那么就先回复一个ACK
以及确认号ack = x + 1
,表示自己已经接收到了客户端的FIN
。服务端发送完剩下的数据后,向客户端发送
FIN
,同样也会附带一个ACK
,用来确认之前的指令,随后服务端进入CLOSE_WAIT
半关闭状态,等待客户端ACK
。客户端接收到
FIN
之后,双方确认数据已经传输完毕,并立即回复一个ACK
,服务端收到后,立即进入closed
状态。但是,客户端需要进入
TIME_WAIT
状态,防止发出去的ACK
没有被服务端接收。服务器端如果没有接收到ACK
,将会重新发送FIN
给客户端,直到超时或者成功。当然,也是因为这个特性,DDos攻击也会存在于这个阶段。最后,客户端真正关闭连接。
TCP通过拥塞控制防止过多数据注入网络,造成过载。
在数据链路层
中存在着流量控制
,当收发数据的时候,双方能知道对方的剩余可用缓冲区
大小,然后调整
发送频率及数据量。
在TCP
当中,存在着比数据链路层更高级的拥塞控制
,需要考虑双方的收发能力及链路的通畅程度。
TCP通过 滑动窗口
及 慢开始
、快恢复
算法来实现拥塞控制。
当存在数据包没有被ACK
,那么就会被认定为网络堵塞
,然后调小 滑动窗口
大小,且门限阈值
降低为原来的 一半
。
拥塞避免,为了防止窗口增加速度过快,设置了一个慢开始门限,窗口每次增加1。
- 当窗口大小小于门限的时候,采用慢开始算法。(指数增大)
- 当窗口大小大于门限的时候,采用拥塞避免算法。(加法增大)
- 当窗口大小大于门限的时候,两种算法都可以。