tcp服务器如何做网络断开修改,[从0到1编写服务器]TCP链接创建与断开状态变化...

上篇介绍了socket编程的准备知识,是否是有一种很想立刻就开始了解网络编程,甚至开始写点代码的感受,别着急,网络编程中还有一个比较重要的概念是TCP/IP,中文名称叫网络传输协议,本质上,TCP/IP是一种协议,同时也是网络编程中最重要的协议之一。TCP/IP涉及到的内容实在太多,无奈笔者才疏学浅,没法把整个TCP/IP介绍给你们,这篇文章的目的主要是基于上一篇文章的前提下,介绍TCP链接三次握手和断开链接四次挥手究竟作了什么?socket的状态有哪些?在各个API执行的过程当中,socket的状态是怎么变化的?但愿经过这篇文章,能让你们对在TCP链接创建与断开过程当中,socket的整个状态变化流程有更深刻的了解。web

几个术语

SYN : 同步序列编号,Synchronize Sequence Numbers,仅在三次握手创建TCP链接时有效。表示一个新的TCP链接请求。编程

ACK : 确认编号,Acknowledgement Number,对TCP请求的确认标志,同时提示对端系统已经成功接收全部数据。服务器

FIN : 结束标志,FINISH,用来结束一个TCP会话,但对应端口仍处于开放状态,准备接收后续数据。网络

TCP三次握手

创建一次链接会有下面的流程并发

1)服务器经过socket(初始化socket)、bind(绑定ip端口)、listen(开始监听服务)完成一次socket链接的创建,并调用accept函数准备好接收外部请求链接,这一步被称为被动打开socket

2)客户端经过socket(初始化socket)完成了链接创建,调用connect函数发起主动打开,此时客户端会发送一个SYN分节J给服务器,J的做用是告诉服务器,在接下来的数据传输过程当中,J是客户端在链接中传输数据的初始序列号函数

3)服务器收到客户端的SYN分节后,须要回复确认信号ACK,J+1,表明服务器已经收到客户端的请求,且已经确认了客户端的初始序列号,同时服务器会发送SYN分节K给客户端,K的做用是告诉客户端,在接下来的数据传输过程当中,K是服务器在链接中传输数据的初始序列号测试

4)客户端收到服务器的SYN分节后,回复确认信号(ACK)K+1。链接创建成功。动画

整个创建链接过程至少须要三个分节,所以被称为TCP三路握手。下面是TCP三次握手的流程图:网络传输协议

d008ee72da4662568ad7210155935214.gif

TCP四次握手

TCP经过三次握手创建链接,然而,断开链接须要四次握手,TCP断开链接的流程描述以下:

一、客户端应用程序调用close函数,TCP中,称首先调用close的那一端为主动关闭,主动关闭的这一端发送FIN分节,意味着已经完成发送数据了;

二、另外一端(即服务器),接收到关闭请求,也收到FIN分节,开始执行被动关闭操做,称为被动关闭的一端。这个FIN分节由TCP确认,发送一个确认分节ACK给客户端,收到的FIN同时也是做为文件结束符传递给应用,意味着应用程序在接收了FIN以后就不会再接收链接上的数据;

三、以后,接收到文件结束符的应用程序会关闭它的socket,服务端的TCP也会发送一个FIN分节;

四、客户端接收到FIN分节,并确认最后的关闭操做,发送ACK分节给服务端。

整个链接过程当中,每一端的关闭和确认关闭都各自须要一个FIN和ACK分节,整个过程一般共须要4个分节,所以也称为TCP四次握手。下面是TCP关闭链接四次握手的流程图:

c284bfd0f4b17ec0960ac09b2776cb74.gif

实际上,网络上的传输是没有链接的,包括TCP也是同样,TCP所谓的"链接"与"断开链接",其实只是一种虚拟的叫法,只不过是在通信的双方维护一个"链接状态",让它看上去好像有链接同样,因此,了解TCP的状态变换是很是重要的,接下来介绍socket的状态以及在TCP创建链接与断开链接过程当中,socket状态的变化。

socket状态

socket共定义了11种状态:LISTEN、SYN-SENT、SYN-RECEIVED、ESTABLISHED、FIN-WAIT-一、FIN-WAIT-一、CLOSE_WAIT、FIN_WAIT、LAST-ACK、TIME-WAIT、CLOSING、CLOSED。

咱们假定A服务请求链接B服务。

LISTEN:开始创建链接,此时socket已经初始化成功,正在等待链接

SYN-SENT:A成功发送链接请求给B,等待对方响应

SYN-RECEIVED:B接收到A的链接请求,并回复了确认进行链接给A,此状态表示正在等待A也回复确认收到此消息

ESTABLISHED:表示链接已经成功创建;这个状态是链接阶段中进行数据传输的正常状态

FIN-WAIT-1:等待主动断开链接请求的确认,或者并发请求被拒绝的断开链接,这种状态一般持续时间很短,比较难捕捉

FIN-WAIT-2:等待B断开链接操做,这个状态一般持续时间也很短,可是若是B发生阻塞或者其余缘由没有关闭链接,那么这个状态就会持续较长时间

CLOSE-WAIT:B已经收到了A的断开链接请求,正在等待本地应用程序发送断开链接请求

CLOSING:A正在等待B的关闭链接确认信号,当A接收到本地程序断开链接的请求后,就发送断开链接请求给B,并进入此状态

LAST-ACK:B等待断开链接的确认信号

TIME-WAIT:等待一段时间,确认B接收到A的关闭链接确认信号

CLOSED:链接彻底关闭

那么在一个完整的TCP链接过程,TCP的状态是怎么转换的呢?

先来看看下面这张图,是UNIX网络编程中,TCP状态变化的经典流程图:

c09ba4efd5e9c6703eab7d55ddbc421d.png

在server端,调用socket函数建立一个sockect,函数返回一个socket文件描述符,调用bind函数绑定ip地址和端口,以后调用listen函数,scokect变成正在监听的socket,进入LISTEN状态,并调用accept等待请求(想要测试LISTEN状态,能够创建socket=>bind=>listen,而后sleep10秒以后退出,启动server以后立刻用netstat命令能够看到)

客户端调用connect,主动打开文件描述符,请求创建链接,此时会触发TCP的三次握手,进入SYN-SENT状态

此时服务器调用了accept正在阻塞阶段,接收到客户端的链接请求后,进入SYN-RECEIVED状态,回复确认报文给客户端,等待客户端确认链接

客户端收到服务器的链接确认报文SYN后,此时TCP已经完成了三次握手,connect函数返回,确认创建链接,转成ESTABLISHED状态,并发送确认报文ACK给服务器。(当第二次握手完成,握手步骤的第二个segment被client接收到的时候,connect函数返回。)

在服务器侧,接收到客户端的确认报文,accept也收到返回,服务器也进入ESTALISHED状态。(握手步骤的第三个分节被server接收到的时候,accept函数返回,即connect返回后通过一半的RTT时间才返回。)

客户端和服务端成功创建"链接"后,就进行开始通讯,此时会调用read/write函数进行读写数据,读写数据完毕后,就准备关闭链接

假定客户端应用程序,收到了服务器的响应报文,完成了通讯过程,准备关闭应用,调用close函数发起主动关闭,此时客户端进入FIN-WAIT1状态,发送FIN分节到服务器,等待服务器确认

服务端收到断开链接请求分节FIN(M),此时read函数返回0,服务器准备执行关闭操做,再也不接收任何数据,并发送确认报文ACK(M+1)给客户端

客户端收到确认分节后,表示服务器已经接收到断开链接请求,此时不会再发送数据并等待服务器断开链接,进入FIN-WAIT2状态

服务器发送确认断开链接后,调用close函数,断开链接,close函数成功返回后,发送FIN分节给客户端,进入LASK-ACK状态,等待客户端的确认

客户端收到服务器的断开链接分节FIN(N)后,发送确认分节ACK给服务器,并进入TIME-WAIT状态,此时会等待足够的时间,大约是最长分节生命期的2倍(2MSL),确认服务器收到断开链接的确认分节,以后就会消失。 服务器收到客户端的断开链接的确认分节ACK(N+1)后,表示链接已经彻底断开了,此时进入CLOSED状态

看完上面的一大段文字可能有点枯燥,甚至有点懵,来看看这张动画图:

7f76d3423e7812dba637fd9755f8be32.gif

总结

本次主要介绍了TCP状态,以及在TCP链接创建和断开过程当中,TCP状态的变化,掌握了这个,对理解网络编程中,各个流程的状态有比较大的帮助,好比在排查服务是否启动的时候,就能够经过netstat -nlp | grep '端口号',查看服务的状态描述字符串,若是是LISTEN状态表示服务已经正常启动,若是服务处于其余状态,则能够经过服务状态来进一步排查问题。

原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。

若是本文对你有帮助,请点个赞吧,谢谢^_^

更多精彩内容,请关注我的公众号。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值