传输层主要的作用就是建立端到端的连接。比如电脑的微信的通信,就需要跨越多个网络设备(交换机和录取)再和微信的服务器建立连接。
传输层需要具有以下的特点:
会话的多复用:如电脑上开启的多个应用,QQ,微信等,这就意味着同时需要建立多个会话。
识别应用程序:通过端口号,来区分不同的应用程序。
分段:在发送数据时,将数据段分为多个部分进行发送,然后在接收端重新组装这些数据段。(TCP)
流量控制:在发送端和接受端,两者发送和接受的带宽不一致时,可以动态的调整带宽。(TCP)
面向连接:确认对方能接收时再发送(TCP)。
可靠性:保证对方一定能收到数据。(TCP)。
TCP 和 UDP 就是实现上述特点的协议。
TCP 报文段 TCP 连接过程 - 三次握手三次握手是个老生常谈的话题,还得在大学时死记硬背这个连接过程,现在想想还蛮好玩的。都说检验一个人是否理解一件事情,就让他给一个从来没有听过的人讲,讲明白了,自然证明也就懂了。其实这就是主动学习和被动学习的体现,大家有兴趣可以查查费曼学习法,讲授给他人,写文章等都是一种主动学习的方式。有点扯远了,回到三次握手的过程,希望能给大家讲清楚。
在谈起连接过程前,先要对 TCP Header 中这几个字段有一个清晰的了解,在上面的导图也提到了,下面着重强调一下:
关于 Flag 字段: 该字段是 1 Byte,共 8 位,如果每一位置 1 后,就代表该 TCP 报文开启了对应的功能,其中三次握手共涉及 3 个字段,注意我这里是用大写的表示,并且只有 1 和 0 两种状态:
SYN 字段:当置 1 时,表示该报文是请求连接的报文段,用于在 TCP 连接时的第一个连接。
ACK 字段:当置 1 时,表示该报文是确认报文,用于表示对方发的请求连接已经收到,这里给予确认。
FIN 字段:当置 1 时,表示发送方已经发送完毕,请求关闭连接。
关于序号字段 seq: 注意这里是小写,共有 4 Byte,32 位。和 IP 层一样,有时当发送的数据超过固定的 MTU 大小时,会将数据包拆成多个小的数据包发送,但数据是有顺序要求,为了保证数据的顺序,就有了该字段 seq,用于表示第一个字节在整个字节流的标号。
关于确认号字段 ack: 和 seq 一样,4 Byte. 表示对收到的数据进行确认,并告诉发送方接下来期待的序列号是什么。
最后还需要明确一点,TCP 建立的是双向的连接,因为在端点的另一方可以是发送方也可能是接收方,明确这点非常重要。
上面看起来比较抽象,一会实际抓包,对照起来看就清晰了。先有个印象,先来分析下 TCP 的连接过程。
一个 TCP 连接会有三个状态:
建立连接的状态
传输数据的状态
关闭连接的转台
先看连接状态:
客户端想要和服务端建立连接:置位 Flag 字段中的 SYN=1,表示请求建立连接。seq = x,表示传送的第一个字节的序号是 x.
服务端收到客户端请求:
置位 Flag 字段中的 ACK=1,表示确认跟你连接链接。ack= x + 1,表示前 x 个字节已经收到,期待传送 x+1个字节。
由于刚才连接过程是客户端到服务端的,同样的,服务端也需要向客户端也发一个请求用于建立连接,这样才是双向连接。正常来说,服务端应该再发一个请求,但由于 TCP 的报头设计,可以将请求功能和确认功能放在一个数据包里,通过 Flag 同时置位 SYN 和 ACK 。这也就是为什么连接时,三次握手而不是四次。
客户端收到服务端的回复,通过 ack=x+1 知道,服务端收到了 x 字节的数据,期待接受 x+1 字节的数据。通过 SYN=1,seq=y 知道服务端想要和自己连接连接。进而回复 ACK=1,seq=x+1,ack=y+1.
传输状态:如何保证数据的可靠性传输?
在客户端给服务传输数据时,如果收到 ACK 的报文,则代表服务端确实收到了传递的数据。考虑这样一种情况,客户端向服务端发送了 seq=10 的报文,但却收到服务端 ack=10 的回复。其实这就代表着,存在丢包的情况,服务端并未收到客户端 seq=10 的包。这时服务端会重新发送 seq=10 的报文,也就是说,在客户端只有成功的接收了服务端的 ACK 包,才会继续向下传递。
如何进行流量控制?