上文介绍了网络通信协议中的UDP协议,本文就带大家了解一下TCP协议。

TCP 协议介绍

TCP是Transmission Control Protocol的缩写,中文名称是:传输控制协议。TCP是一种面向连接的、可靠的、基于字节流(流就是指不间断的数据结构,你可以把它想象成排水管中的水流)的传输层通信协议,由IETF的RFC 793定义。在计算机网络OSI模型中,它和UDP协议一样处于第四层——传输层,和UDP是同一层内另一个重要的传输协议,可靠性高于UDP协议。
OSI七层模型.png

在当一台计算机想要与另一台计算机进行通信时,两台计算机之间的通信需要畅通且可靠,这样才能保证正确收发数据。例如,当你需要查看网页或查看电子邮件时,希望完整且按顺序查看网页,而不丢失任何内容。当你下载文件时,希望获得的是完整的文件,而不仅仅是文件的一部分,因为如果数据丢失或乱序,都不是你希望得到的结果,于是就用到了TCP。

TCP 的特点

1.TCP 提供一种面向连接的、可靠的字节流服务

面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”,这样能建立可靠的连接。建立连接,是为数据的可靠传输打下了基础。且TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。

2.仅支持单播传输

每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。

3.TCP 使用校验和,确认和重传机制来保证可靠传输

对于可靠传输,判断丢包,误码靠的是TCP的段编号以及确认号。TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。

4.TCP 给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复

5.拥塞控制

当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞。

6.TCP 并不能保证数据一定会被对方接收到,TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。

TCP 报文

TCP报文格式.png
16位源端口号:发送方对应的端口号,源端口和源IP地址的作用是标识报文的返回地址。

16位目的端口号:接收方的端口号,接收方通过这个端口号来确定把数据送给哪个应用。

32位序号:TCP对从进程中接收到的字节进行编号,为的是当数据到接收端时,接收端可以按照这个序号把数据进行重组,保证数据的正确性。

32位确认序号:确认号是对发送端确认信息的,由他来告诉发送端这个序号之前的数据都已经收到了。

4位首部长度:首部数据结构的长度,包括TCP头大小,指示何处数据开始。

6位保留:目前还没有用到该功能,这些位必须是0。留作以后作为拓展功能用。

标志:6位标志域。按照顺序排列是:URG、ACK、PSH、RST、SYN、FIN,其功能分别为:
UGR:紧急指针有效位,可不经过缓存直接传给应用。紧急标志为"1"表明该位有效。
ACK:确认标志,确认标志栏有效。
PSH:标志位为1时要求接收方尽快将数据段送达应用层,但还是需要经过缓存。
RST:重新建立TCP连接。
SYN:建立TCP连接。
FIN:断开TCP连接。

16位窗口值:本地可接收数据段的数目,这个值大小是可变的,最大为65535字节。窗口值越大传输速率越快,反之则越慢。

16位校验和:用来做差错控制,若接收端的校验结果与发送端一致,则说明数据是正确的,反之则说明数据受到了破坏,接收端将会抛弃这段数据。校验和覆盖了整个的TCP报文段:这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证的。

16位紧急指针:与URG配合使用。如果URG标志没有被设置,紧急域作为填充。

32位选项:TCP首部的可选信息,例如创建该数据的时间等。如果没有选项就表示这个1字节的域等于0。

数据:该TCP协议包负载的数据。

TCP 三次握手

所谓三次握手(Three-Way Handshake)就是指建立一个TCP连接时,需要Client和Server总共发送3个包以确认连接的建立。在socket编程中,这一过程由Client执行connect来触发,整个流程如下图所示:
TCP三次握手.png

  1. 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=X,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  2. 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=X+1,随机产生一个值seq=Y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  3. 第三次握手:Client收到确认后,检查ack是否为X+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=Y+1,并将该数据包发送给Server,Server检查ack是否为Y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

当然这个过程我们也可以看做Client和Server之间的“交流”,其意义如下:

  1. 第一次握手:Client发送网络包,Server收到了。这样Server就能得出结论:Client的发送能力、Server的接收能力是正常的。
  2. 第二次握手:Server发包,Client收到了。这样就能得出结论:Server的接收、发送能力,Client的接收、发送能力是正常的。从Client的视角来看,我接到了Server发送过来的响应数据包,说明Server接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,Server的接收、发送能力正常。而另一方面,我收到了Server的响应数据包,说明我第一次发送的网络包成功到达Server,这样,我自己的发送和接收能力也是正常的。
  3. 第三次握手:Client发包,Server收到了。这样Server就能得出结论:Client的接收、发送能力,Server的发送、接收能力是正常的。 第一、二次握手后,Server并不知道Client的接收能力以及自己的发送能力是否正常。而在第三次握手时,Server收到了Client对第二次握手作的回应。从Server的角度看,我在第二次握手时的响应数据发送出去了,Client接收到了。所以,我的发送能力是正常的。而Client的接收能力也是正常的。

经历了上面的三次握手过程,Client和Server都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。

TCP 四次挥手

TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。Client或Server均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。
TCP四次挥手.png

这里以Client执行挥手操作:

  1. 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  2. 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  3. 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  4. 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

为什么TCP建立只需要三步反而断开却要四步?
这是因为Server在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给Client。若Client和Server要断开连接,这时Client会向Server发送FIN,Server收到后就会回复ACK,但有可能Server还有数据未传输完成,所以ACK和FIN并没有一起回复给Client,等到Server的数据传输完成后,才会发送FIN给Client,Client收到Server的FIN回复ACK这时双方就断开连接了,这也是为什么断开为什么比建立要多一步。

TCP常用端口及其应用

TCP常用端口及其应用.png

文章名: 《网络通信学习之——TCP与UDP协议(2)》

文章链接:https://www.yfriend.xyz/602.html

除特别注明外,文章均为深度博客所创,转载时请注明本文出处及文章链接
Last modification:May 3rd, 2020 at 05:02 pm
如果觉得我的文章对你有用,请随意赞赏