内容整理自协议森林、计算机网络(第三版)、RFC793协议中文版,简单介绍一些概念。
传输层的主要功能是实现分布式进程通信。传输层协议在源主机应用进程和目的主机应用进程之间建立端到端连接
。
端口(port)
端口是伴随着传输层诞生的概念。它可以将网络层的IP通信分送到各个通信通道。
套接字socket的概念
在网络环境中,标识一个进程必须同时使用ip地址和端口号。RFC793协议定义的socket是由IP地址与对应的端口号组成(IP:端口)。如(202.1.2.5:30022)。
术语socket有多种不同含义
-
RFC793中socket=IP:端口
-
网络软件编程中,API是网络应用程序的可编程接口,也称socket
-
API中的一个函数名也称为socket
-
Socket是操作系统提供的一个编程接口,它用来代表某个网络通信。应用程序通过socket来调用系统内核中处理网络协议的模块,内核模块会负责具体的网络协议的实施。
考虑多重协议识别的全网唯一标识
三元组(半相关):协议、IP、端口
五元组(相关):协议,客户端,服务端。如:TCP,202.1.2.5:30022,121.5.21.2:80。
TCP协议复杂,但传输可靠。UDP协议简单,但传输不可靠。
UDP(用户数据报协议)和TCP(传输控制协议)都是传输层协议。传输报文(segment)。
UDP协议主要特点
-
面向报文
-
不需要建立连接
-
无法保证数据传输可靠
-
检测到分组出错,它就丢弃分组,既不确认也不通知重传
UDP只是做了传输协议能够做的最少工作。
UDP的数据包同样分为头部(header)和数据(payload)两部分。
UDP是传输层(transport layer)协议,这意味着UDP的数据包需要经过IP协议的封装(encapsulation),然后通过IP协议传输到目的电脑。
随后UDP包在目的电脑拆封,并将信息送到相应端口的缓存中。
TCP协议主要特点
有序和可靠
有序是通过将文本流分段并编号实现的。可靠是通过ACK回复和重复发送(retransmission)实现的。
-
支持面向连接的传输服务
-
支持字节流传输 (如果以byte为单位,就叫做文本流)
-
支持全双工通信
-
支持同时建立多个并发的TCP连接(TCP协议支持一个服务端与多个客户端建立多个TCP连接,也支持一个客户端与多个服务端建立多个TCP连接)
-
支持可靠的传输服务
IP协议和UDP协议采用的是数据包的方式传送,后发出的数据包可能早到,我们并不能保证数据到达的次序。TCP协议确保了数据到达的顺序与文本流顺序相符。
比如我们有一个大文件要从本地主机发送到远程主机,如果是按照“流”接收到的话,我们可以一边接收,一边将文本流存入文件系统。这样,等到“流”接收完了,硬盘写入操作也已经完成。如果采取UDP的传输方式,我们需要等到所有的数据到达后,进行排序,才能组装成大的文件。
可靠性
在每收到一个正确的、符合次序的片段之后,就向发送方(也就是连接的另一段)发送一个特殊的TCP片段,用来知会(ACK,acknowledge)发送方:我已经收到那个片段了。这个特殊的TCP片段叫做ACK回复。如果一个片段序号为L,对应ACK回复有回复号L+1,也就是接收方期待接收的下一个发送片段的序号。如果发送方在一定时间等待之后,还是没有收到ACK回复,那么它推断之前发送的片段一定发生了异常。发送方会重复发送(retransmit)那个出现异常的片段,等待ACK回复,如果还没有收到,那么再重复发送原片段… 直到收到该片段对应的ACK回复(回复号为L+1的ACK)。
TCP在协议层次结构中的地位
+------+ +-----+ +-----+ +-----+
|Telnet| | FTP | |Voice| ... | | Application Level
+------+ +-----+ +-----+ +-----+
| | | |
+-----+ +-----+ +-----+
| TCP | | RTP | ... | | Host Level
+-----+ +-----+ +-----+
| | |
+-------------------------------+
| Internet Protocol & ICMP | Gateway Level
+-------------------------------+
|
+---------------------------+
| Local Network Protocol | Network Level
+---------------------------+
Protocol Relationships
应用 | 应用层协议 | 传输层协议 |
---|---|---|
电子邮件 | SMTP | TCP |
远程终端 | Telnet | TCP |
web | HTTP | TCP |
文件传输 | FTP | TCP |
远程文件服务器 | NFS | 通常UDP |
流式多媒体 | 通常专用 | UDP或TCP |
IP电话 | 通常专用 | UDP或TCP |
网络管理 | SNMP | UDP或TCP |
选路协议 | RIP | 通常UDP |
名字转换 | DNS | 通常UDP |
TCP报文格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Data | |U|A|P|R|S|F| |
|Offset |Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP Header Format
源端口(Source Port):16 bits
目的端口(Destination Port):16 bits
系列号(Sequence Number):32 bits
确认号(Acknowledgment Number):32 bits
控制位(Control Bits):6 bits(从左到右):
数据偏移(Data Offset): 4 bits
保留(Reserved):6 bits
URG:紧急指针字段有效(Urgent Pointer field significant)
ACK:确认头部字段有效(Acknowledgment field significant)
PSH:强制函数(Push Function)
RST:重置连接(Reset the connection)
SYN:同步系列号码(Synchronize sequence numbers)
FIN:再没有来自发送者的数据(No more data from sender)
窗口(Window):16 bits
接收端正准备接收的数据八位字节的数目,开始于确认字段(acknowledgment)指示的位置。
校验和(Checksum):16 bits
TCP头格式
-
一个TCP头部需要包含出发端口(source port)和目的地端口(destination port)。
-
每个TCP片段都有序列号(sequence number)。这些序列号最终将数据部分的文本片段整理成为文本流
-
ACK是一位(bit)。只有ACK位设定的时候,回复号(Acknowledgement number)才有效。ACK回复号说明了接收方期待接收的下一个片段,所以ACK回复号为最后接收到的片段序号加1。
定义TCP报头
typedef struct _tcphdr {
byte source_port[2]; //发送端端口号,16位
byte dest_port[2]; //接收端端口号,16位
byte sequence_no[4]; //32位,标示消息端的数据位于全体数据块的某一字节的数字
byte ack_no[4]; //32位,确认号,标示接收端对于发送端接收到数据块数值
byte offset_reser_con[2];//数据偏移4位,预留6位,控制位6为
byte window[2]; //窗口16位
byte checksum[2]; //校验码,16位
byte urgen_pointer[2]; //16位,紧急数据指针
byte options[3]; //选祥和填充,32位
}TCP_HEADER;
TCP连接建立与释放
三次握手
三次握手的目的是同步连接双方的序列号(ISN, Initial Sequence Number)和确认号并交换TCP窗口大小信息。
-
建立连接时,客户端发送SYN包(SYN seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
-
服务器收到SYN包,必须确认客户的SYN(ACK=x+1),同时自己也发送一个SYN包(SYN seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
-
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
四次挥手
-
客户端发送一个FIN,用来关闭客户A到服务器B的数据传送(FIN seq=x+2 ACK=y+1)。
-
服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(ACK=x+3)。和SYN一样,一个FIN将占用一个序号。
-
服务器关闭与客户端的连接,发送一个FIN给客户端A(FIN seq=y+1)。
-
客户端发回ACK报文确认,并将确认序号设置为收到序号加1(ACK=y+2)。
TCP状态
|-----> CLOSE ----->|
| |
|接收ACK,不发送 |
| |
LAST_ACK LISTEN
| |
|发送FIN | 接收SYN并发送SYN & ACK
| |
ClOSE_WAIT SYN_RCVD
| |
|接受FIN,发送ACK | 接收ACK,不发送
| |
|<----- ESTABLISHED <-----|
SYN洪泛攻击
攻击发送大量SYN报文段,而不完成三次握手的第三步。通常从多个源发送SYN能够加大攻击力度,产生DDoS(分布式拒绝)SYN洪泛攻击。
防御系统:SYN cookies
超时重传和快重传
超时重传
重新发送的机制:当发送方送出一个TCP片段后,将开始计时(RTO时间之后),等待该TCP片段的ACK回复。如果接收方正确接收到符合次序的片段,接收方会利用ACK片段回复发送方。发送方得到ACK回复后,继续移动窗口,发送接下来的TCP片段。如果直到计时完成,发送方还是没有收到ACK回复,那么发送方推断之前发送的TCP片段丢失,因此重新发送之前的TCP片段。这个计时等待的时间叫做重新发送超时时间(RTO, retransmission timeout)。
快重传
由于IP包的传输是无序的,所以接收方有可能先收到后发出的片段,也就是乱序(out-of-order)片段。乱序片段的序号并不等于最近发出的ACK回复号。已接收的文本流和乱序片段之间将出现空洞(hole),也就是等待接收的空位。比如已经接收了正常片段5,6,7,此时又接收乱序片段9。这时片段8依然空缺,片段8的位置就是一个空洞。
TCP协议规定,当接收方收到乱序片段的时候,需要重复发送ACK。比如接收到乱序片段9的时候,接收方需要回复ACK。回复号为8 (7+1)。此后接收方如果继续收到乱序片段(序号不是8的片段),将再次重复发送ACK=8。当发送方收到3个ACK=8的回复时,发送方推断片段8丢失。即使此时片段8的计时器还没有超时,发送方会打断计时,直接重新发送片段8,这就是快速重新发送机制(fast-retransmission)。
窗口
流量控制
阻塞控制