TCP

TCP相较于UDP,具有可靠性,但是相对的占用系统资源;而UDP没有TCP那些可靠的机制,所以相比较于TCP更快。

单工、半双工、全双工

根据通信双方的分工和信号传输方向可将通信分为三种方式:单工、半双工与全双工

单工:数据只能在单个方向上传输。比如广播 半双工:数据可以在两个方向上传输,在同一时刻只允许一个方向传输。 比如对讲机 全双工:数据可以在两个方向上传输,在同一时刻也允许两个方向传输。比如手机通话

TCP 和 UDP 都是全双工

TCP 协议

TCP(Transmission Control Protocol)传输控制协议,是主机对主机层的传输控制协议,用于提供可靠的连接服务。为了保证TCP协议的可靠性,保证数据正确的传输给对方,在连接时需要进行三次握手,确保双方可以正常通信,在断开连接时需要进行四次挥手,确保双方数据都传输完毕,保证数据传输完毕。

三次握手协议

三次握手(Three-Way-Handshake)即建立TCP连接,就是指建立一个TCP连接时,客户端和服务端总共需要发送三个包确认连接的建立

借用一下这个小例子,来描述三次握手的流程:

土豆土豆 我是地瓜,收到请回答 地瓜收到,土豆收到请回答 土豆收到

步骤1和2:确认地瓜可以正常收到土豆的消息 步骤2和3:确认土豆可以正常收到地瓜的消息

这三步就可以保证土豆和地瓜正常通信,这就是三次握手。下面是具体流程:

  1. 客户端发送第一次握手请求,并携带SYN=j(j是一个唯一的随机数,代表此次请求),此时客户端此时变为已发送的状态(SYN_SEND)

  2. 服务端接收到客户端的握手请求,此时进入 LISTEN 打开状态

  3. 服务端发送ACK确认包,此时是第二次握手,ACK=j+1表示是哪个请求,并再次发送SYN=k(k也是唯一随机数,用来代表此次请求)

  4. 客户但接收到ACK信息,此时客户端进入 ESTABLISHED 状态,代表客户端到服务端信息发送正常

  5. 客户端发送ACK确认信息给服务端,此时是第三次握手,告诉服务端可以正常收到他的信息

  6. 服务端收到ACK信息后,将状态变为ESTABLISHED,双方可以正常通信, 整个握手流程结束

四次挥手协议

四次挥手(Four-Way-Wavehand)即终止TCP连接,就是断开一个TCP连接时,客户端和服务短短总共需要发送四个包确认连接的断开

目的:保证客户端和服务端都没有消息传递了再关闭

男朋友(客户端):我有点事先不聊了 女朋友(服务端):好的,等下,我还有点事没讲完 ... 女朋友(服务端):好了,我没事了挂了吧 男朋友(客户端):喂.... (随即男朋友也挂断了电话)

通过四次通信,确认tcp通信已经完成,并关闭连接,这就是四次挥手,下面是具体流程:

  1. 客户端发送FIN M(M是发送id),表示客户端要结束了,此时客户端进入FIN_WAIT_1 状态

  2. 服务端接收到请求后,进入CLOSE_WAIT状态(等待关闭),再向客户端发送ACK确认包,告诉客户端,我已经接收到了关闭请求

  3. 等到服务端数据传送完毕,发送FIN N给客户端,告诉客户端处理完毕,即将进入关闭状态

  4. 客户端接收到 FIN N,返回ACK确认包,此时服务端进入关闭状态

TCP 长连接、短连接

长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接(心跳机制),一般需要自己做在线维持。 过程: 连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接

短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,比如http连接

TCP通信原理

对于TCP通信来说,每个TCP Socket的内核中都有一个发送缓冲区和一个接收缓冲区,TCP全双工的工作模式及TCP的滑动窗口就是依赖于这两个独立的Buffer和该Buffer的填充状态

进程调用Socket的send发送数据的时候,一般情况下是将数据从应用层用户的Buffer里复制到Socket的内核发送缓冲区,然后send就会在上层返回。换句话说,send返回时,数据不一定会被发送到对端。

接收端接收到数据后,将数据放在接收缓冲区中,若应用进程一直没有调用Socket的read方法进行读取,那么该数据会一直被缓存在接收缓冲区内。不管进程是否读取Socket,对端发来的数据都会经过内核接收并缓存到Socket的内核接收缓冲区。 read索要做的工作,就是把内核接收缓冲区中的数据复制到应用层用户的Buffer里。

滑动窗口协议

滑动窗口协议用于控制流量,TCP滑动窗口分为接受窗口和发送窗口。滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。

视频演示:优酷-TCP sliding window

视频中发送端向接收端发送 segment 数据片段,接收端接收到数据片段后给发送端发送ACK确认包。当发送端接收到3个ack信号时,即发送端滑动窗口满了的时候,才会再次发送,如果未满,说明接收端仍然在处理。而接收端只有在收到3个segemnt信号时,滑动窗口才会移动,才能再次接收segement。从而达到限流的目的。

最后更新于