TCP/IP协议簇学习之TCP连接

TCP连接主要包括三个方面的内容:连接建立,数据传输和连接终止。

连接建立

连接建立的过程采用三次握手。

1,客户端发送一个包含SYN字段的报文段给服务器,该报文段的序号为随机值,假设为8000;

2,服务器收到SYN报文段以后,产生一个随机值,假设为15000,将序号填入报文段中,同时在ACK字段中填入客户端期待收到的下一个序号,即8001,同时设置接收窗口大小,将此报文段发送给客户端;

3,客户端收到服务器发来的报文段以后,设置接收窗口大小,并在ACK字段中填入期待收到的下一个报文段的序号,将此报文段给客户端,注意,该报文段的序号为8000(不携带数据的ACK报文段不消耗序号)。如果有数据要发送,可以将第三次握手连同数据一同发往服务器,则此时携带了数据,因此报文段序号为8001。

那么为什么要进行三次握手呢?我的理解是要实现双向认证,一方面,客户端要查看收到的报文段的ACK是不是所连的服务器发来的。另一方面,服务器也要查看收到的报文段中的ACK是不是已分配了连接资源的客户端发来的。

数据传输

连接建立以后,客户端和服务器之间可以相互传输数据了。

传输数据的时候,假设客户端要发送2000个字节,并且,客户端的发送报文段序号为8001和ACK为15001,服务器收到报文段以后,在报文段序号中填入15001,ACK中填入10001,同时,假设服务器要发送2000字节数据。客户端收到服务器发来的报文段以后,假设客户端不发送数据了,那么在报文段序号中填入10001,ACK中填入17001。不携带数据的ACK报文段不消耗序号。

推送数据

首先,TCP推送数据需要考虑两个方面的问题,一方面是发方进程到发方TCP,另一方面是发方TCP到收方TCP。采用了缓存技术来进行流量控制。就像之前流量控制的博客说过的,采用Nagle算法会等待收到ACK或者发送窗口满了以后再发送。但是TCP可以通过PSH选项设置立即发送。

对于紧急数据,需要被特殊对待,紧急数据需要在报文段的紧急字段(URG)置1。虽然紧急数据可以插在报文段的最前面,但它并不能改变收方处理的顺序,只是对于紧急报文段,收方会进行特殊对待。

连接终止

连接终止有两种模型:三次挥手和面向半连接的四次挥手。

三次挥手的过程:

服务器一般是被动关闭的,因此考虑关闭是客户端发起的。

1,客户端发送一个报文段,将FIN置1,同时,报文段的序号假设为x,ACK假设为y(客户端发送FIN是由操作系统发送的,操作系统发现客户端关闭了连接(譬如按ctrl+c终止的时候),就发送一个FIN报文段给服务器)。

2,服务器收到FIN报文段以后,将序号填入y,并在ACK中填入x+1,同时将FIN字段置1,发送给客户端。

3,客户端收到FIN报文段以后,将序号填入x(不消耗序号),ACK填入y+1,发送给服务器。

四次挥手的过程:

引入半关闭的概念:TCP是全双工的,半关闭的时候可以只关闭写,不关闭读。

1,客户端发送一个报文段,将FIN置1,同时,报文段的序号假设为x,ACK假设为y(客户端发送FIN是由操作系统发送的,操作系统发现客户端关闭了连接(譬如按ctrl+c终止的时候),就发送一个FIN报文段给服务器)。此时客户端关闭了“写通道“,但仍然可以读数据。

2,服务器收到FIN报文段以后,将序号填入y-1(不消耗序号,填的上一个序号),并在ACK中填入x+1发送给客户端。此时服务器不发送FIN,因为还有些数据没处理完。

3,客户端收到FIN报文段以后,什么都不干,保持沉默。服务器将处理完的数据发给客户端,此时客户端依然会发送ACK给服务器。等服务器发现数据都发完了,服务器关闭“写通道”,操作系统就发送了一个FIN报文段给客户端。并且序号为z,ACK为x+1。

3,客户端收到FIN报文段以后,将序号填入x(不消耗序号),ACK填入z+1,发送给服务器。服务器收到ACK以后,关闭了连接。



猜你喜欢

转载自blog.csdn.net/u012260341/article/details/79787739