TCP协议
概念
所谓协议,是指通信的双方,为了保证通信效果,特意在通信形式和内容上的一致协商。在生活中,协议处处可见,例如规定好的交通出行统一靠右行驶,这其实就是一种协议。在计算机世界中,计算机与计算机之间的沟通更加抽象复杂,为了保证能够各种应用场景下的正确通信,众多计算机世界中的协议应运而生。这其中最重要的当属TCP协议和Http协议。【文末:常见计算机协议】
TCP,英文全称Transmission control protocol,直译为:传输控制协议。是一种面向连接,可靠的,基于字节流的传输层通信协议。它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。
TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
可靠的连接
TCP是机器与机器间传输信息的基础协议,也是人与人联立联系的准则。在真正的学习TCP之前我们首先来看看人与人之间的联系如何保证可靠。
上面两幅图可以得出一个结论:
在连接的过程中要想保证通信双发是可靠的,必须有三次会话的过程;
而在断开连接的过程中,必须保证有四次会话过程;
所以,在TCP的连接过程中也会发送三次消息,俗称三次握手,在断开连接的过程中也必须发送四次消息,俗称四次挥手。这样才能够在不可靠的网络环境中建立可靠的通信。
TCP的报文结构
在开始讲TCP连接过程前,还是先看看TCP报文的格式如图1所示。数据报包此时由IP头部+TCP头部+TCP数据组成。不带选项的TCP头部是20字节长,而带选项的,TCP头部最长可达60字节。常见的选项包括最大的大小(MSS),时间戳(传输控制时使用)、窗口缩放(流量控制时使用)、选择性ACK(传输控制时使用)。
图1 IP数据报中TCP封装
TCP头部
了解了TCP的报文大体结构以后,我们来具体看下TCP头部字段如图2所示。
不要将确认序号ACK与标志位中的ACK搞混了
图2 TCP头部结构
源端口/目的端口
源端口号(16位),标识主机上发起传送的应用程序。
目的端口(16位)标识主机上传送要到达的应用程序。
源端和目的端的端口号,用于寻找发端和收端应用进程。这两个值加上I P首部中的源端I P地址和目的端I P地址唯一确定一个T C P连接。一个I P地址和一个端口号有时也称为一个套接字( s o c k e t)。套接字对(s o c k e t p a i r)(包含客户I P地址、客户端口号、服务器 I P地址和服务器端口号的四元组 )可唯一确定互联网络中每个T C P连接的双方。
注意:TCP协议通过使用"端口"来标识源端和目标端的应用进程。端口号可以使用0到65535之间的任何数字。在收到服务请求时,操作系统动态地为客户端的应用程序分配端口号。在服务器端,每种服务在"众所周知的端口"(Well-Know Port)为用户提供服务。
序列号
序列号(Sequence Number),占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。(谁发送数据谁设置这个值)。
在报文结构中通过序列号来标识发送端到接收端的数据的顺序。序号是32bit的无符号数,序号到达232-1后又从0开始。
在TCP传输中,每一个字节都是有序号的,从0开始。通过序号的方式保存数据的顺序,TCP会给每个字节赋予一个序列号,接收端接受到之后进行重新排列成为需要的数据。
例如 : 我已经发送了前100字节的数据,那么我下一个发送的包(如果发送窗口还有空间)的SEQ就是101,比如要发送10字节的数据,那么下一个包中的数据的字节编号就是 101 - 110. 之后如果继续发送的话,序号就是从111开始。如果接收端接到了这个10字节的包的话,便会返回一个 ACK 为 111 的包,表示前面110个字节已经成功接收。
确认号
在TCP/IP协议中,如果接收方成功的接收到数据,那么会回复一个ACK数据。通常ACK信号有自己固定的格式,长度大小,由接收方回复给发送方。
接收端接收到数据后,即可通过确认号(ACK)来回送给发送端,让发送端知道数据已被接受。这个ACK号是由接收到的数据的序列号加1,代表接收端希望接收的下一个数据的序列号。(注:ACK是不占用序列号的,原因是接收端发送ACK给发送端后,发送端的ISN是等于此时接收到的ACK号)。
头部长度
头部长度占4位,标识该TCP头部有多少个32bit位(4字节)。因为4位能够表示的最大数字是1111,即15,所以TCP头部最长能有15个4字节,15*4=60。这样就能够确定下来TCP的头部最长是60个字节。
保留位
4bit+CWR+ECE总共六个bit位,目前没有使用,值都是0。
六个标志位
- SYN(synchronous建立联机)
表示同步序号,是TCP/IP建立连接时的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,SYN标志位和ACK标志位搭配使用,当请求连接的时候,SYN=1,ACK=0;
服务器使用SYN+ACK应答表示接收到了这个信息。连接被响应的时候,SYN=1,ACK=1;
最后客户机再以ACK消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。
SYN是TCP连接的第一个包,非常小的一种数据包。SYN 攻击包括大量此类的包,由于这些包看上去来自实际不存在的站点,因此无法有效进行处理。每个机器的欺骗包都要花几秒钟进行尝试方可放弃提供正常响应。
- ACK(acknowledgement 确认标志)
此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;
- PSH(push传送)
这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;
- FIN(finish结束)
带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。
表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。当一个FIN标志的TCP数据包发送到一台计算机的特定端口,如果这台计算机响应了这个数据,并且反馈回来一个RST标志的TCP包,就表明这台计算机上没有打开这个端口,但是这台计算机是存在的;如果这台计算机没有反馈回来任何数据包,这就表明,这台被扫描的计算机存在这个端口。
- RST(reset重置)
重置连接,不过一搬表示断开一个连接,例如,主机192.168.3.27 访问主机211.150.84.8;但主机84.8并没有监听对应端口,这时它会向主机3.27发送一个RST位置的TCP包断开连接。也被用来拒绝错误和非法的数据包;
- URG(urgent紧急)
此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。
Tips :
MSS:(TCP MAXIMUM SEGMENT SIZE )
只出现在syn报文段中,TCP协议中的最大分段大小。在TCP协议中,比较大的数据包会被拆分成几个小的数据包来传送,这个值就是设置了最大到多少可以不用分段,再大了就要分段了。
一般来说,MSS的值在不分段的情况会越大越好,比如一个外出接口的MSS值是MTU减去IP和TCP首部长度。
窗口大小
表示源主机最大能接受多少字节。
TCP校验和
包含TCP首部和TCP数据段,这是一个强制性的字段,一定是由发送端计算和存储,由接收端进行验证。
紧急指针(16bit)
只有当URG标志置为1时该字段才有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一段发送紧急数据的一种方式。
TCP选项
至少1个字节的可变长字段,标识哪个选项有效。Kind=0:选项表结束, Kind=1:无操作, Kind=2:最大报文段长度,Kind=3:窗口扩大因子, Kind=8:时间戳。
TCP建立连接
下面详细解释了TCP建立连接的三次握手,随图附上每次握手的TCP报文结构,方便大家理解。
TCP断开连接
下图详细解释了TCP断开连接的四次挥手过程,以及每一次挥手都做了什么工作。随图附上每次挥手的TCP报文结构,方便大家理解。
TCP的简单总结
通常TCP连接是由客户端向服务器发起和断开的。因为只有服务器在监听端口,客户端上没有监听端口,所以客户端无法接收主动来的连接。而客户端获得了自己想要的资源或者服务之后,就会断开连接。
其实TCP的连接和断开过程跟邂逅一场爱情一模一样:在碰到心仪的男生之前,女孩都是充满期待的,就像就像TCP协议中,服务器对新的客户端都会置于Listen(等待响应)状态。而你要做的就是主动上前。。。
“你也常来这家咖啡厅吧,他们家的焦糖玛奇朵非常棒。”
SYN=1, seq=x(客户端发送完消息,进入SYN_SENT状态)。
“我也是,我喜欢榛仁玛奇朵。我住这附近,你呢?”
SYN=1, ACK=1, ack=x+1, seq=y(服务器原来为LISTEN状态,发送后,进入SYN_RCVD状态)
“好巧,我也住这附近。他们店的玛奇朵是招牌喔。”
ACK=1,ack=y+1, seq=x+1
发送完后,客户端从SYN_SENT状态过入ESTABLISED状态。
服务器收到后包,从SYN_RCVD状态进入ESTABLISTED状态。
对于离别时,男生应该主动一些
“我还有事要走了,你加我微信吧!”
FIN=1, seq=u
客户端从ESTABLISED状态进入FIN-WAIT-1状态。
“好,我发给你~哈哈你的头像好可爱”
ACK=1, ack=u+1, seq=v
发送后,服务器从ESTABLISHED状态,进入CLOSE-WAIT状态。
收到后,客户端从FIN-WAIT-1状态,进入FIN-WAIT-2状态。
女孩接着说道:“快去忙你的吧!已经发过去了。今天好开心!”
FIN=1, ACK=1, ack=u+1, seq=w
发送后,服务器从CLOSE-WAIT状态,进入LAST_ACK状态。
“收到了。遇到你我也很开心,拜拜”
ACK=1, ack=w+1, seq=u+1
发送后,客户端从FIN-WAIT-2状态,进入TIME-WAIT状态。
收到后,服务器从LAST-ACK状态,进入CLOSED状态。
然后,她离开了。你凝望着她,一再回头,直到消失在视线外。
等待2MSL后,客户端从TIME-WAIT状态,进入CLOSED状态。
TCP小结
- 每一次通讯,都带有seq序列码。 每一次通讯,状态都会变更。
- SYN=1在握手阶段双方各发送一次。FIN=1在挥手阶段双方各发送一次。
- 有确认码的时候ACK=1,必带有确认号ack。 ack在上一条接收到的序号上+1。
附录
TCP的状态
LISTEN:
侦听来自远方的TCPport的连接请求
SYN-SENT:
再发送连接请求后等待匹配的连接请求
SYN-RECEIVED:
再收到和发送一个连接请求后等待对方对连接请求的确认
ESTABLISHED:
代表一个打开的连接
FIN-WAIT-1:
等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN-WAIT-2:
从远程TCP等待连接中断请求
CLOSE-WAIT:
等待从本地用户发来的连接中断请求
CLOSING:
等待远程TCP对连接中断的确认
LAST-ACK:
等待原来的发向远程TCP的连接中断请求的确认
TIME-WAIT:
等待足够的时间以确保远程TCP接收到连接中断请求的确认
CLOSED:
没有不论什么连接状态
状态迁移
建立连接时的状态变迁
一开始,建立连接之前服务器和客户端的状态都为CLOSED。服务器创建socket后开始监听,变为LISTEN状态。客户端请求建立连接,向服务器发送SYN报文,客户端的状态变为SYN_SENT。服务器收到客户端的报文后向客户端发送ACK和SYN报文,此时服务器的状态变为SYN_RCVD。然后,客户端收到ACK、SYN,就向服务器发送ACK,客户端状态变为ESTABLISHED,服务器收到客户端的ACK后也变为ESTABLISHED。此时,3次握手完成,连接建立!
断开连接时的状态变迁
由于tcp连接是全双工的,断开连接会比建立连接麻烦一点点。客户端先向服务器发送FIN报文,请求断开连接,其状态变为FIN_WAIT1。服务器收到FIN后向客户端发生ACK,服务器状态变为CLOSE_WAIT。客户端收到ACK后就进入FIN_WAIT2状态。此时连接已经断开了一半了。如果服务器还有数据要发送给客户端,就会继续发送。直到发完了,就发送FIN报文,此时服务器进入LAST_ACK状态。客户端收到服务器的FIN后,马上发送ACK给服务器,此时客户端进入TIME_WAIT状态,再过了2MSL长的时间后进入CLOSED状态。服务器收到客户端的ACK就进入CLOSED状态。
CLOSING
至此,还有一个状态没有提及:CLOSING状态。CLOSING状态表示客户端发送了FIN,但没有收到服务器的ACK,却收到了服务器的FIN。这种情况发生在服务器发送的ACK丢包的时候,因为网络传输有时会有意外。
状态流程
客户端的状态流程
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服务器的状态流程
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
SEQ和ACK的计算
TCP实战 : 只有明白了Seq和ack的计算,才算是真正的明白了TCP协议。
Tips:
序列号:
只要自己上次是发送SYN或者是发送FIN包,那么本次发送的序列号就要+1,所以+1的动作只发生在握手阶段,挥手阶段以及握手后的第一次发送数据阶段。
对于中间传输数据阶段,序列号则等于上次的序列号 + 上次发送的数据长度,如果数据长度为0,则序列号与上次保持一致,可以理解为seq = seq + 0。
确认号:
在握手和挥手阶段,确认号是收到的序列号加1,
传输数据阶段则是收到的序列号 + 收到的数据长度
如果对方携带应用层数据长度为0,则ack与收到的序列号相同,不要+1,也可以这样理解:因为没有发送数据,所以A期待B下次发送过来的第一个字节的序号不变
- 第一次握手 : 只发送SYN包
SYN = 1
Seq = 0(随机初始化的序列号,表示客户端的序列号从0开始)
- 第二次握手 : 回复ACK确认包,
SYN=1
ACK=1
Seq =0(随机初始化的序列号,表示服务器的序列号从0开始 )
Ack =0+1 (在握手和挥手阶段,确认号是收到的序列号加1,收到的序列号是【1】发送过来的初始序列号0,所以ack = 1,表示下次收到客户端的序列号应该从1开始)
- 第三次握手 : 回复ACK确认包,三次握手成功,开始传输数据。
Seq =1(只要自己上次是发送SYN或者是发送FIN包,那么本次发送的序列号就要+1,上次是【1】第一次握手发送的SYN包seq = 0,所以本次客户端自己的Seq要+1)
Ack =0 + 1(在握手和挥手阶段,确认号是收到的序列号加1,收到的序列号是【2】发送过来的初始序列号0,所以ack=1,表示下次收到服务端的序列号应该从1开始。)
ACK=1
-------------------------------------------下面开始传输数据-,整个传输数据阶段都回带上确认标识ACK-----------------------------------------------
- 客户端发送给服务器725字节的数据。(客户端第一次发送数据)
Seq =1 (传输数据阶段,序列号则等于上次的序列号【3回复的ACK包时seq = 1】 + 上次发送的数据长度【3回复ACK包时,数据长度为0】 = 1 + 0 = 1)
数据 = 725字节
Ack = 1
- 服务器收到了725字节数据,回复确认的ACK包(服务器第一次接收数据)
Seq = 1(只要自己上次是发送SYN或者是发送FIN包,那么本次发送的序列号就要+1,上次是【2】第二次握手发送的SYN包seq = 0,所以本次服务器自己的Seq要+1)
Ack =726(传输数据阶段则是收到的序列号【4发送过来的seq = 0】 + 收到的数据长度【4发送过来的725】 = 1 + 725 = 726)
ACK = 1
- 服务器发送给客户端1448个字节的数据(服务器第一次发送数据)
Seq = 1,(传输数据阶段,序列号则等于上次的序列号【5回复的ACK包时seq=1】 + 上次发送的数据长度【5回复ACK包时,数据长度为0】= 1 + 0 = 1)
Ack = 726
数据 = 1448字节
ACK=1
- 客户端收到了1448个字节数据(客户端第一次接受数据)
Seq = 726(传输数据阶段,序列号则等于上次的序列号【4 发送数据时,seq = 1】 + 上次发送的数据长度【4发送的725字节】 = 1 + 725 = 726)
Ack =1449(传输数据阶段则是收到的序列号【6发送过来的seq = 1】 + 收到的数据长度【6发送过来的1448】 = 1 + 1448 = 1449)
ACK=1
--------------------------------------为了方便理解,接下来只让服务器给客户端发送数据,这样只需要计算一个方向的sql,ack即可------------------------------
- 服务器发送给客户端1448个字节的数据(服务器第二次发送数据)
Seq = 1449,(传输数据阶段,序列号则等于上次的序列号【6发送数据时,seq=1】 + 上次发送的数据长度【6发送的1448字节】 = 1 + 1448 = 1449 )
Ack = 726
数据 = 1448字节
ACK=1
- 客户端收到了1448个字节数据(客户端第二次接受数据),回复ACK消息
Seq = 726(传输数据阶段,序列号则等于上次的序列号【4 发送数据时,seq = 1】 + 上次发送的数据长度【4发送的725字节】 = 1 + 725 = 726)实际上就是客户端一直没发送数据
Ack =2897(传输数据阶段则是收到的序列号【8发送过来的seq = 1449】 + 收到的数据长度【8发送过来的1448】 = 1449 + 1448 = 2897)
ACK=1
- 服务器发送给客户端1448个字节的数据(服务器第三次发送数据)
Seq = 2897,(传输数据阶段,序列号则等于上次的序列号【8发送数据时,seq=1449】 + 上次发送的数据长度【8发送的1448字节】 = 1449 + 1448 = 2897 )
Ack = 726
数据 = 1448字节
ACK=1
- 客户端收到了1448个字节数据(客户端第三次次接受数据),回复ACK消息
Seq = 726(传输数据阶段,序列号则等于上次的序列号【4 发送数据时,seq = 1】 + 上次发送的数据长度【4发送的725字节】 = 1 + 725 = 726)实际上就是客户端一直没发送数据
Ack =4345(传输数据阶段则是收到的序列号【10发送过来的seq = 2897】 + 收到的数据长度【10发送过来的1448】 = 2897 + 1448 = 4345)
ACK=1
TCP经典案例题
为什么连接的时候是三次握手,关闭的时候却是四次挥手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。
为什么要4次挥手?
确保数据能够完整传输。
当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,
再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
为什么不能用两次握手进行连接?
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
断开链接的时候,为什么不去掉第二步,直接进行第三步呢?
因为,第二步中,服务器端通知应用程序并获得反馈信息可能需要可观的时间,这可能涉及人机交互操作,也可能服务器应用层暂时还不想关闭连接。第二步结束后,服务器还可以继续通过这条连接发送数据给客户端,客户端已经不能发送数据了,但是仍然可以回复ACK。第二步中服务器立即发送确认是为了防止客户端重传FIN报文。
当然也有可能双方同时来连接,这个时候通信双方是对等的,比如BGP peer之间就是对等的,翻译成中文为BGP对等体,也算是贴切。如果双发使用非监听端口发起连接,这样最终需要断开其中一条多余的连接。如果双发都使用自己监听的端口发起连接,那就成了四次握手,正好建立起一条双向连接。
也有可能服务器在不想继续为客户端提供服务了,主动断开连接。不过这种情况对于TCP而言仍然是普通的四次挥手。
还有可能客户端和服务器同时断开连接,仍然是发送四个报文,你可以把它看做是四次挥手,但是它不再是普通的四次挥手。因为这4个报文在时间上有重叠。就TCP状态机的迁移而言,也和普通的四次挥手不同。将不再进入FIN-WAIT-2状态。
为什么SYN和FIN会消耗一个序列号
为什么在建立连接的时候,发送的 SYN 包大小(payload)明明是0字节,但是接收端却返回 ACK = 1 ,还有断开连接的时候 FIN 包也被视为含有1字节的数据。
原因是 SYN 和 FIN 信号都是需要 acknowledgement 的,也就是你必须回复这个信号,如果它不占有一个字节的话,要如何判断你是回复这个信号还是回复这个信号之前的包呢?
例如:如果 FIN 信号不占用一个字节,回复 FIN 的 ack 包就可能被误认为是回复之前的数据包被重新发送了一次,第二次挥手无法完成,连接也就无法正常关闭了。
常见计算机网络协议
协议简称 | 协议全称 | 中文名称 |
TCP | transmission control protocol | 传输控制协议 |
IP | Internet Protocol | 因特网协议 |
UDP | User Datagram Protocol | 用户数据报协议 |
HTTP | hypertext transfer protocol | 超文本传输协议 |
FTP | File Transfer Protocol | 文件传输协议 |
SMTP | simple mail transfer protocol | 简单邮件传输协议 |
POP3 | post office protocol-version3 | 邮局协议3 |
IMAP | internet mail access portocol | 因特网邮件访问协议 |
TLS | Transport Layer Security | 安全协议 |
SSL | Secure Sockets Layer | 安全协议 |