TCP/IP详解学习笔记(10)-TCP链接的创建与停止

TCP是一个面向链接的协议,因此在链接双方发送数据以前,都须要首先创建一条链接。这和前面讲到的协议彻底不一样。前面讲的全部协议都只是发送数据而已,大多数都不关心发送的数据是否是送到,UDP尤为明显,从编程的角度来讲,UDP编程也要简单的多----UDP都不用考虑数据分片。 服务器

书中用telnet登录退出来解释TCP协议链接的创建和停止的过程,能够看到,TCP链接的创建能够简单的称为三次握手,而链接的停止则能够叫作四次握手网络

1.链接的创建

在创建链接的时候,客户端首先向服务器申请打开某一个端口(用SYN段等于1的TCP报文),而后服务器端发回一个ACK报文通知客户端请求报文收到,客户端收到确认报文之后再次发出确认报文确认刚才服务器端发出的确认报文(绕口么),至此,链接的创建完成。这就叫作三次握手。若是打算让双方都作好准备的话,必定要发送三次报文,并且只须要三次报文就能够了。 并发

能够想见,若是再加上TCP的超时重传机制,那么TCP就彻底能够保证一个数据包被送到目的地。 socket

2.结束链接

TCP有一个特别的概念叫作half-close,这个概念是说,TCP的链接是全双工(能够同时发送和接收)链接,所以在关闭链接的时候,必须关闭传和送两个方向上的链接。客户机给服务器一个FIN为1的TCP报文,而后服务器返回给客户端一个确认ACK报文,而且发送一个FIN报文,当客户机回复ACK报文后(四次握手),链接就结束了。 学习

3.最大报文长度

在创建链接的时候,通讯的双方要互相确认对方的最大报文长度(MSS),以便通讯。通常这个SYN长度是MTU减去固定IP首部和TCP首部长度。对于一个以太网,通常能够达到1460字节。固然若是对于非本地的IP,这个MSS可能就只有536字节,并且,若是中间的传输网络的MSS更佳的小的话,这个值还会变得更小。 spa

4.TCP的状态迁移图

书P182页给出了TCP的状态图,这是一个看起来比较复杂的状态迁移图,由于它包含了两个部分---服务器的状态迁移和客户端的状态迁移,若是从某一个角度出发来看这个图,就会清晰许多,这里面的服务器和客户端都不是绝对的,发送数据的就是客户端,接受数据的就是服务器。 .net

4.1.客户端应用程序的状态迁移图

客户端的状态能够用以下的流程来表示: 线程

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED 设计

以上流程是在程序正常的状况下应该有的流程,从书中的图中能够看到,在创建链接时,当客户端收到SYN报文的ACK之后,客户端就打开了数据交互地链接。而结束链接则一般是客户端主动结束的,客户端结束应用程序之后,须要经历FIN_WAIT_1,FIN_WAIT_2等状态,这些状态的迁移就是前面提到的结束链接的四次握手。

4.2.服务器的状态迁移图

服务器的状态能够用以下的流程来表示:

CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

在创建链接的时候,服务器端是在第三次握手以后才进入数据交互状态,而关闭链接则是在关闭链接的第二次握手之后(注意不是第四次)。而关闭之后还要等待客户端给出最后的ACK包才能进入初始的状态。

4.3.其余状态迁移

书中的图还有一些其余的状态迁移,这些状态迁移针对服务器和客户端两方面的总结以下

  1. LISTEN->SYN_SENT,对于这个解释就很简单了,服务器有时候也要打开链接的嘛。
  2. SYN_SENT->SYN收到,服务器和客户端在SYN_SENT状态下若是收到SYN数据报,则都须要发送SYN的ACK数据报并把本身的状态调整到SYN收到状态,准备进入ESTABLISHED
  3. SYN_SENT->CLOSED,在发送超时的状况下,会返回到CLOSED状态。
  4. SYN_收到->LISTEN,若是受到RST包,会返回到LISTEN状态。
  5. SYN_收到->FIN_WAIT_1,这个迁移是说,能够不用到ESTABLISHED状态,而能够直接跳转到FIN_WAIT_1状态并等待关闭。

4.4.2MSL等待状态

书中给的图里面,有一个TIME_WAIT等待状态,这个状态又叫作2MSL状态,说的是在TIME_WAIT2发送了最后一个ACK数据报之后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方均可以正常结束,可是,问题也来了。

因为插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是没法再次使用同一个插口的,对于客户程序还好一些,可是对于服务程序,例如httpd,它老是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了不这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然能够从新启动服务器,可是这个服务器仍是要平静的等待2MSL时间的过去才能进行下一次链接。

4.5.FIN_WAIT_2状态

这就是著名的半关闭的状态了,这是在关闭链接时,客户端和服务器两次握手以后的状态。在这个状态下,应用程序还有接受数据的能力,可是已经没法发送数据,可是也有一种多是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态。

5.RST,同时打开和同时关闭

RST是另外一种关闭链接的方式,应用程序应该能够判断RST包的真实性,便是否为异常停止。而同时打开和同时关闭则是两种特殊的TCP状态,发生的几率很小。

6.TCP服务器设计

前面曾经讲述过UDP的服务器设计,能够发现UDP的服务器彻底不须要所谓的并发机制,它只要创建一个数据输入队列就能够。可是TCP不一样,TCP服务器对于每个链接都须要创建一个独立的进程(或者是轻量级的,线程),来保证对话的独立性。因此TCP服务器是并发的。并且TCP还须要配备一个呼入链接请求队列(UDP服务器也一样不须要),来为每个链接请求创建对话进程,这也就是为何各类TCP服务器都有一个最大链接数的缘由。而根据源主机的IP和端口号码,服务器能够很轻松的区别出不一样的会话,来进行数据的分发。

掌握本章的状态迁移图才是学习本章的关键。

相关文章
相关标签/搜索