TCP/IP协议

TCP原理

TCP每发送一个报文段,就启动一个定时器,如果在定时器超时之后还没有收到ACK确认,就重传该报文。 如图所示,数据包由A的缓冲区发往B,B在收到数据包以后,回发一个ACK确认包给A,之后A将该数据包从缓冲区释放。因此,该数据包会一直缓存在A的缓冲区,直到一个ACK确认为止。
TCP/IP协议

TCP/IP工作层

TCP/IP工作在第4层,(传输层)在TCP/IP协议簇中,有两个不同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议),它们分别承载不同的应用。TCP协议提供可靠的服务,UDP协议提供不可靠但是高效的服务。
TCP/IP的特点:
(1)分层是TCP/IP乃至网络通信最核心的策略和模式,分层使得所有的网络应用程序不用关心底层链路传输的细节,也使得不同类型的网络有效地互通。
(2)封装就是在应用程序在发送数据的过程中,每一层都增加一些首部信息,这些信息用于和接收端同层次进行沟通。
(3)在接收端的处理过程就正好相反,也就是所谓的分用策略,数据从底层到最上层的应用程序过程中,数据被逐层拆分,每一层取出自己所需要的信息。

在TCP/IP协议中,TCP协议提供可靠的面向连接的服务;三次握手(建立连接)和四次挥手(关闭连接)

三次握手(建立连接)

TCP/IP协议
(1)第一次握手时:建立连接时,客户端A发送SYN包【SYN=1,seq=x】到服务器B并进入SYN_SEND状态等待服务器确认
(2)第二次握手:服务器收到SYN包,必须确认客户A的SYN包,同时自己也发送一个SYN包,即SYN+ACK包【SYN=1,ACK=1,seq=有,ack=y+1】,此时服务器进入SYN_RECV状态
(3)第三次握手:客户端A收到服务器B的SYN+ACk包,向服务端B发送确认包ACK【ACK=1,seq=x+1,ack=y+1】,发送完毕,此时客户端和服务器进入ESTABLISHED状态,完成三次握手,客户机开始向服务器传送数据。

三次握手完成后,客户端和服务器就建立了TCP连接。这时可以调用accept函数获得此连接。三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的***和确认号并交换TCP 窗口大小信息

四次挥手(关闭连接)

TCP/IP协议
TCP连接拆除需要发送四个包,因此成为四次挥手,客户端服务器均可主动发起挥手动作.因为TCP连接时全双工的,因此每个方向都必须进行关闭。这个原则是当一方完成他的数据传送任务后就可以发送FIN来终值这个方向上的连接,收到一个FIN只意味着这个方向没有数据流动,一个TCP连接在收到FIN后仍能发送数据,。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。TCP要保证所有可能情况下,使得所有数据都被投递,当你关闭一个SOCKER时,主动关闭一段的SOCKER进入TIME_WAIT状态,而被动关闭的一方进入CLOSED状态,这就保证所有数据都能被传输。

(1)首先A,B端的TCP进程都处于estiblish状态,当A的应运程序传送完报文就会主动关闭连接,A会停止发送报文,(但是还会接受)并向 B发送【FIN=1,seq=u】数据,之后进入FIN-WAIT-1状态
(2)B接收到A的请求之后,会通知应运进程,A以不在发送数据,同时B会向A发送ACK确认数据,【ACK=1,seq=v,ack=u+1】B进入CLOSE-WAIT状态,A接到B的方向数据后进入FIN-WAIT2状态,此时A到B的方向的连接已近关闭,即半连接状态
(3)当B的应用程序没有东西要传送时,B应用进程就会发出被动关闭请求,此时B向A发送ACK确认数据【ACK=1,seq=u+1,ack=w+1】数据,进入LAST-ACK状态;
(4)A接收到B发送的数据后,向B发送ACK确认数据,【ACk=1,seq=u+1,ack=w+1】进入TIME-WAIT状态,等待2msl之后关闭连接进入CLOSED状态,B到A的连接关闭,TCP连接关闭。
两个知识点:
1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到客户端的SYN报文的建立连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到 ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于 LAST_ACK状态下的SOCKET可