传输层,是站在应用的角度,解决数据在传输中可能遇到的各种问题。传输层协议有两个,一个是传输控制协议(Transmission Control Protocol),就是TCP协议;另一个是用户数据报协议(User Datagram Protocol),就是UDP协议。我们先讨论TCP。
先看一下TCP的封装格式:
看上去内容挺多,我们“庖丁解牛”,慢慢来。
第一行,源端口和目的端口。
这里“端口”的意思不是指设备的物理插孔,而是传输层用来标识电脑上不同的应用程序的。如果把一台电脑看成一座城市,应用程序看成一户人家,那么,端口号就是他家的门牌号。
端口号占2个字节,理论上最多可以标识65536个应用程序。IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)对端口号做了分配和规划:
0~1023之间的端口号是知名端口号,被固定分配给一些很“知名”的应用。比如HTTP为80、DNS为53、Telnet为23,等等。
1024~49151之间的端口号是注册端口号,可用于任何应用程序的服务端。但如果想固定使用,需向IANA注册登记,防止重复。
这两种端口号都用于应用程序服务端。比如,你电脑的IP地址是192.168.1.20,你做了个网站,提供Web服务,那我在浏览器敲入192.168.1.20:80,就可以访问到你的网站。
我们把(IP地址:端口号)叫套接字(Socket),唯一地表示一台电脑中的一个应用程序及其提供的服务。
49152~65535之间的端口号是动态端口号,在客户端由应用程序随机使用,做为一个“连接”的源端口。连接拆除后,端口被释放。
Sequence Number序号,填写封装的数据中第一个字节的编号。TCP是面向字节的,会对发送的数据每个字节都进行编号。已发送成功的数据序号可以循环使用。
Acknowledgement Number确认号,向发送端确认已经正确收到的最后一个字节序号+1。
举个栗子:电脑A向电脑B发送1000个字节的数据,序号填写为1。电脑B正确收到后,填写确认号1001(数据最后一个字节序号是1000),告诉电脑A前面的我都收到了,下次从1001序号开始发。
有确认?嗯,靠谱!
Data Offset,填写的是TCP头部,也就是这张“快递单”有多大,一般为20字节。
Reserved保留没有使用。
接下来是六个标志位:
URG,配合后面的Urgent Pointer(紧急指针)一起解释。如果URG为1,表示本段数据中开头位置到紧急指针所指位置为紧急数据。最常见的紧急数据是Ctrl+C。
ACK填写为1,确认号Acknowledgement Number才有效。TCP连接建立后传输的所有数据段ACK都必须填写为1。
PSH填写1,表示接收方收到数据后不要放入缓冲区,而是立即把数据交给应用程序处理。常用于交互式应用,如Telnet等。
RST填写1,表示当前TCP连接出现严重问题,必须拆除重连。
SYN在建立TCP连接时使用。SYN=1且ACK=0,表示这是一个连接请求报文。SYN=1且ACK=1,表示这是一个同意建立连接的应答报文。
FIN填写1表示当前报文是一个拆除连接的请求报文。
Window窗口,用于流量控制。
Checksum校验和,用于接收方检查数据段在传输过程中是否出错。
Options选项,常用于通信双方协商一些参数,如MSS、Window乘积因子等等。
MSS(Maximum Segment Size)最大报文段长度。TCP建立连接时双方会协商发送的数据最大字节数(TCP封装中的data,不包括前面说的这些TCP头部)。MSS常见为1460字节,加上TCP头部20字节,再加IP头部20字节,刚好等于以太网中的MTU值1500字节,这样IP就不用分片了。
这样做的好处有两方面,一是防止接收方缓冲区较小而发送的数据段很大;二是可以充分利用网络带宽。MSS太小,网络利用率不高;太大,IP又要分片重组,增加额外开销。
TCP提供了面向连接的“端到端”服务,这个“端”,不是电脑终端,而是端口。准确地说,是套接字!
一个TCP连接=(套接字1,套接字2)=(IP地址1:端口号1,IP地址2:端口号2)。
你看,TCP提供的是一对一的“VIP服务”!
TCP协议规定,在传输数据前,通信双方必须先建立“连接”。注意这个“连接”是抽象的逻辑连接,并不考虑底层物理线路。如同打电话,我们只关心电话通不通,而不关心电话线是怎么架设的。这也是我们常说的“透明传输”。
TCP通过“三次握手”建立连接。
第一次握手,客户端向服务端发送连接请求报文(SYN=1且ACK=0),序号为0,确认号为0(因ACK=0,无意义);
第二次握手,服务端收到后,向客户端发送同意连接报文(SYN=1且ACK=1),序号为0,确认号为1(告诉客户端刚才的序号0收到了,下次从序号1开始发);
第三次握手,客户端收到后,向服务端发送同意报文(ACK=1),序号为1,确认号为1。连接建立完成。
接下来,就可以传数据了。你看,TCP是不是像打电话,拨通了才能说话。
小Q:为什么要三次握手?两次行不行?
欢迎留言讨论。