TCP连接与断开

TCP 连接与断开

1. TCP 状态

  • LISTEN:侦听来自远方的TCP端口的连接请求

  • SYN-SENT:再发送连接请求后等待匹配的连接请求

  • SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认

  • ESTABLISHED:代表一个打开的连接

  • FIN-WAIT-1:先前的连接中断请求的确认,等待的是fin的确认,通过发送第一个fin触发

  • FIN-WAIT-2:等待另一方的终端请求,收到第一个fin的ack后触发

  • CLOSE-WAIT:等待从本地用户发来的连接中断请求,发送第一个fin的ack后触发

  • CLOSING:等待远程TCP对连接中断的确认(只有同时关闭才会进入此状态,不在进入FIN-WAIT-2状态

  • LAST-ACK:等待原来的发向远程TCP的连接中断请求的确认(等待最后一个ack)

  • TIME-WAIT:等待足够的时间以确保远程TCP接收到连接中断请求的确认

  • CLOSED:没有任何连接状态

2. TCP状态图

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

3. 相关知识点

1.连接的建立

在建立连接的时候,客户端首先向服务器申请打开某一个端口(用SYN段等于1的TCP报文),然后服务器端发回一个ACK报文通知客户端请求报文收到,客户端收到确认报文以后再次发出确认报文确认刚才服务器端发出的确认报文(绕口么),至此,连接的建立完成。这就叫做三次握手。如果打算让双方都做好准备的话,一定要发送三次报文,而且只需要三次报文就可以了。
如果再加上TCP的超时重传机制,那么TCP就完全可以保证一个数据包被送到目的地,保证链接建立。

半连接队列与全连接队列

半连接是指服务端接收到客户端的syn连接请求,并发送syn与ack给客户端后,等待客户端的ack(第三次握手)。此时会放到半连接队列。半连接攻击的实现就是客户端不进行第三次握手,导致服务器半连接队列溢出,无法处理新的连接。
全连接队列是与客户端建立了连接的队列,调用accept会从该队列中取出一个连接。

2.结束连接

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

3.最大报文长度

在建立连接的时候,通信的双方要互相确认对方的最大报文长度(MSS),以便通信。一般这个长度是MTU减去固定IP首部和TCP首部长度。对于一个以太网,一般可以达到1460字节。当然如果对于非本地的IP,这个MSS可能就只有536字节,而且,如果中间的传输网络的MSS更加小的话,这个值还会变得更小。
备注:最大传输单元(Maximum Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络接口卡、串口等)。IP层发送的数据超过MTU后会自动分片。MTU越大,则一个协议数据单元的承载的有效数据就越长,通信效率也越高。MTU越大,传送相同的用户数据所需的数据包个数也越低
MTU也不是越大越好,因为MTU越大, 传送一个数据包的延迟也越大;并且MTU越大,数据包中 bit位发生错误的概率也越大

4.TCP的状态迁移图

这是一个看起来比较复杂的状态迁移图,因为它包含了两个部分—服务器的状态迁移和客户端的状态迁移,如果从某一个角度出发来看这个图,就会清晰许多(从server或者client开始),这里面的服务器和客户端都不是绝对的,发送数据的就是客户端,接受数据的就是服务器。

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

客户端的状态可以用如下的流程来表示:

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

以上流程是在程序正常的情况下应该有的流程,在建立连接时,当客户端收到SYN报文的ACK以后,客户端就打开了数据交互地连接。而结束连接则通常是客户端主动结束的,客户端结束应用程序以后,需要经历FIN_WAIT_1,FIN_WAIT_2等状态,这些状态的迁移就是前面提到的结束连接的四次握手。

2.服务器的状态迁移图

服务器的状态可以用如下的流程来表示:

CLOSED->LISTEN->SYN_RECV->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

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

3.其他状态迁移

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

LISTEN->SYN_SENT,对于这个解释就很简单了,服务器有时候也要打开连接的嘛。

SYN_SENT->SYN_RECV,服务器和客户端在SYN_SENT状态下如果收到SYN数据报,则都需要发送SYN的ACK数据报并把自己的状态调整到SYN_RECV状态,准备进入ESTABLISHED

SYN_SENT->CLOSED,在发送超时的情况下,会返回到CLOSED状态。

SYN_RECV->LISTEN,如果受到RST包,会返回到LISTEN状态。

SYN_RECV->FIN_WAIT_1,这个迁移是说,可以不用到ESTABLISHED状态,而可以直接跳转到FIN_WAIT_1状态并等待关闭。

4 2MSL等待状态

有一个TIME_WAIT等待状态,这个状态又叫做2MSL状态,说的是在TIME_WAIT2发送了最后一个ACK数据报以后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束。再就是等待在网络上延迟的一些数据,保证这些数据不会影响下一次通信。

由于插口的2MSL状态(socket四元组),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。(个人认为服务器关闭连接最大的问题还是socket占用一个fd,而服务器的fd是有限的

5.FIN_WAIT_2状态

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

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

RST是另一种关闭连接的方式,应用程序应该可以判断RST包的真实性,即是否为异常中止。而同时打开和同时关闭则是两种特殊的TCP状态,发生的概率很小。(不太理解前面这句话,服务器一般会通过设置so_linger 来夭折一个连接,并丢弃发送缓冲区的所有数据,发送一个RST给客户端,而不进入time_wait状态)

6.TCP服务器设计

UDP的服务器完全不需要所谓的并发机制,它只要建立一个数据输入队列就可以(无连接的)。但是TCP不同,TCP服务器对于每一个连接都需要建立一个独立的进程(或者是轻量级的,线程),来保证对话的独立性。所以TCP服务器是并发的。而且TCP还需要配备一个呼入连接请求队列(UDP服务器也同样不需要),来为每一个连接请求建立对话进程,这也就是为什么各种TCP服务器都有一个最大连接数的原因。而根据源主机的IP和端口号码,服务器可以很轻松的区别出不同的会话,来进行数据的分发。

7. tcp连接建立不采用两次的原因

“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致以后的某个时间才到达server。本来这是一个早已失效的报文段(client认为失效了),但server收到此失效的连接请求报文段后,就误认为是client发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,(对服务器来说)新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送ack包。这种情况会浪费服务器资源

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值