TCP四次挥手(断开连接)(未完待续)

正常情况下,调用close(),其中产生的一个效果就是发送FIN。

断开为什么需要四次握手:

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能到CLOSE状态

注:主动关闭一方会进入TIME_WAIT状态,以下假设Client是主动方

1、如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,保证能再次接收 FIN 并发送 ACK。(猜测: FIN超时时间应该小于MSL,否则Client等待2MSL,也可能接收不到FIN)

2、如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。

大多数服务器端一般执行被动关闭,服务器不会进入TIME_WAIT状态。

服务端为了解决这个TIME_WAIT问题,可选择的方式有三种:

?  保证由客户端主动发起关闭(即做为B端)

?  关闭的时候使用RST的方式

?  对处于TIME_WAIT状态的TCP允许重用(SO_REUSEADDR)

Q: 编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思?

A: 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用

端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息,

指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧

使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期

望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不

可能。

是否说明需要TCP状态处于TIME_WAIT才可以执行SO_REUSEADDR

对于TIME_WAIT的插曲:

当建立一个TCP连接时,服务器端会继续用原有端口监听,同时用这个端口与客户端通信。而客户端默认情况下会使用一个随机端口与服务器端的监听端口通信。有时候,为了服务器端的安全性,我们需要对客户端进行验证,即限定某个IP某个特定端口的客户端。客户端可以使用bind来使用特定的端口。对于服务器端,当设置了SO_REUSEADDR选项时,它可以在2MSL内启动并listen成功。但是对于客户端,当使用bind并设置SO_REUSEADDR时,如果在2MSL内启动,虽然bind会成功,但是在windows平台上connect会失败。而在linux上则不存在这个问题。(我的实验平台:winxp, ubuntu7.10)

要解决windows平台的这个问题,可以设置SO_LINGER选项。SO_LINGER选项决定调用close时TCP的行为。SO_LINGER涉及到linger结构体,如果设置结构体中l_onoff为非0,l_linger为0,那么调用close时TCP连接会立刻断开,TCP不会将发送缓冲中未发送的数据发送,而是立即发送一个RST报文给对方,这个时候TCP连接就不会进入TIME_WAIT状态。如你所见,这样做虽然解决了问题,但是并不安全。通过以上方式设置SO_LINGER状态,等同于设置SO_DONTLINGER状态。

时间: 2024-08-26 14:50:40

TCP四次挥手(断开连接)(未完待续)的相关文章

TCP四次挥手断开连接详解

TCP四次挥手. 数据传输结束后,通信的双方都可释放连接.现在A和B都处于ESTABLISHED状态.A的应用程序先向TCP发出连接释放报文段,主动关闭TCP连接.A把连接释放报文段的首部FIN置为1,序号seq=u,它等于前面已传送过的数据的最后一个字节的序号加1.这时A进入FIN-WAIT-1状态,等待B的确认. B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1.然后B就进入CLOSE-WAIT状态.TCP

TCP 三次握手建立连接,四次挥手断开连接,图解详细分析,有个疑点求帮忙解答????

继文章  http://blog.csdn.net/simonchi/article/details/41722511   之后,我觉得有必要来详细的说一下TCP的三次握手和四次挥手的过程,帮助大家理解这个过程. 首先来看一下tcpdump抓取的网络数据包,如何抓包分析参考 上面给出的链接 图中红色框选的是三次握手建立连接 第一次:客户端发送SYN报文,并设置seq=0, 第二次:服务端收到SYN报文,知道对方要求建立连接,发送SYN和ACK报文,并设置seq=0,ack=0(第一次的seq)+

ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)

要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person Get() { return new Person {Id = 1, Name = "refuge"}; } //控制器需要继承 Controller 类 public IActionResult Get() { return Ok("hello world"); }

学习TCP/IP - TCP三次握手连接和四次握手断开连接

TCP连接 一.为什么需要TCP 链路层将位流封装成数据帧,同时屏蔽了底层物理层的复杂性; 网络层定义了IP地址,划分了网段,使得源计算机可以快速找到目标计算机,但它无法保证数据准确到达. 所以在传输层定义了TCP协议,它是面向连接的可靠传输协议, 二.TCP如何建立连接 2.1) TCP三次握手建立连接 TCP三次握手创建连接 a. 由于TCP是面向连接的,所以有服务端和客户端之分.服务端先在对应的端口监听(LISTENING), 等待客户端发送的tcp连接请求. b. A机器向B机器发起TC

网络编程(未完待续)

三次握手四次挥手 半连接池: 限制的是同一时刻的请求数,而非连接数 这是三次握手 syn_sent是客户端发送请求时的状态listen是服务端一开始的接听状态syn_rcvd是服务端收到请求后的状态established是客户端建立连接后的状态(客户端到服务端这端的管道建立)eatablished是服务端建立连接后的状态(服务端到客户端这端的管道建立)seq = x 请求的时候附带的序列号(暗号)ack = x+1 是回复请求, 并把刚刚拿到的序列号+1 四次挥手 C/S B/S client<

TCP三次握手建立链接与四次挥手断开链接

防伪码:从基础开始,一步一个脚印 先简单介绍一下TCP协议. TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层协议.很复杂,但属于不论程序员还是运维人员都必会的基本功. 面向对象的--连接双方在通信前需要预先建立一条连接,这犹如实际生活中的打电话,电话必须拨通了以后才能交流. 可靠的--TCP协议中有诸多的规则来保障通信链路的可靠性,含应用数据分隔.重传机制.对首部和数据校验.对收到的数据进行排序,然后交给应用层.接收

TCP为什么是三次握手,为什么不是两次或者四次 &amp;&amp; TCP四次挥手

这是一个很有意思的问题~ 首先,我们要知道TCP是全双工的,即客户端在给服务器端发送信息的同时,服务器端也可以给客户端发送信息.而半双工的意思是A可以给B发,B也可以给A发,但是A在给B发的时候,B不能给A发,即不同时,为半双工. 单工为只能A给B发,B不能给A发: 或者是只能B给A发,不能A给B发. 我们假设A和B是通信的双方.我理解的握手实际上就是通信,发一次信息就是进行一次握手. 第一次握手: A给B打电话说,你可以听到我说话吗? 第二次握手: B收到了A的信息,然后对A说: 我可以听得到

TCP四次挥手

tcp四次挥手详解: 挥手之前,客户端和服务器端都处于建立连接状态,客户端是主动关闭,服务器是被动关闭 (1)首先客户端发送连接释放报文FIN=1,seq=u,主动关闭连接,并不在发送数据.TCP规定FIN报文不能携带数据,但是消耗一个序号,这时A进入FIN_WAIT_1(终止等待1) (2)服务器收到连接释放报文后,发送确认,ACK=1,seq=v,ack=u+1(因为上面消耗了一个序号),这个之后服务器进入了close_wait状态,并通知高层应用程序,因此从可客户端到服务器发送的这个连接就

计算机网络(五),TCP四次挥手

目录 1.TCP四次挥手详情 2.为什么会有TIME-WAIT状态 3.为什么需要四次握手才能断开连接 4.服务器出现大量CLOSE_WAIT的原因 五.TCP四次挥手 1.TCP四次挥手详情 (1)一开始双方都属于已连接状态 (2)客户端发送一个报文段:FIN=1,seq=u.FIN表示连接关闭请求,seq是之前最后一个发送的数据的标号+1.客户端进入关闭等待状态1(FIN-WAIT-1) (3)服务端接收到关闭连接请求之后,通知程序需要关闭连接,然后返回一个报文段:ACK=1,seq=v,a

TCP四次挥手及原因

一.TCP四次挥手 MSL是TCP报文里面最大生存时间,它是任何报文段被丢弃前在网络内的最长时间. 第一次挥手:A->B,A向B发出释放连接请求的报文,其中FIN(终止位) = 1,seq(序列号)=u:在A发送完之后,A的TCP客户端进入FIN-WAIT-1(终止等待1)状态.此时A还是可以进行收数据的 第二次挥手:B->A:B在收到A的连接释放请求后,随即向A发送确认报文.其中ACK=1,seq=v,ack(确认号) = u +1;在B发送完毕后,B的服务器端进入CLOSE_WAIT(关闭