tcp建立连接

tcp连接的建立需要经历”三次握手“的过程。过程如下

  1. client发送SYN包(值为j)以及SEQ包到server端,此时client进入SYN_SEND状态。此为第一次握手。
  2. server端收到SYN包后,发送一个ACK(值为seq+1)确认包和SYN(值为k)给client,此时server进入SYN_RECV状态。此为第二次握手。
  3. client收到SYN+ACK包后,向server发送一个ACK(值为k+1),该包发送完成后,client和server均进入ESTABLISH状态。此为第三次握手。

client和server两端状态变化如下:

client:
CLOSED->SYN_SEND->ESTABLISH
server:
CLOSED->LISTEN->SYN_RECV->ESTABLISH

为什么是3次握手,不是2次或者4次呢?

建立一个可靠的tcp连接,至少是要3次的,既然3次就足够,为什么还要4次。
那2次可以么。假设2次就建立连接,那么会出现如下情况。
client发送一个A请求,由于网络原因,没有那么快送达server端。此时client便废弃该请求,重新发起请求B,请求B成功送达server端,并得到响应。
如果此时便建立连接,若之前的请求A终于到达server端了,由于请求的格式都是正常的,于是也发送响应回去client,而client则认为该请求已经被废弃。于是server端就一直挂着这个请求,造成资源浪费。

因此,才需要让client再发送一次确认给server端,server接收确认后才建立连接,便可以避免这种情况了。

tcp连接释放

Tcp释放连接的过程需要经历“四次挥手”的过程,为什么建立连接只需要3次握手,而释放连接需要进行4次挥手呢?

很简单,因为TCP连接是全双工(Full Duplex)的,因此造成了两个方向都需要进行关闭。

怎么理解呢?

client和server,需要关闭连接,此时client通知server我要关闭连接了,此时关闭的只会是client这一端的连接,而server端并未关闭,它依旧能够向client发送数据。

当然,关闭连接也可以是server作为主动方的。

接下来以client主动断开与server端的连接为场景来描述整个过程,我们把它分为两个阶段,分别为client端关闭连接和server端关闭连接。

先上图

第一阶段

  1. 首先client会发送一个FIN包给server(同时还有ack和seq包),这是要告诉server,我已经没有数据要发给你了,此时client处于FIN_WAIT_1状态。接收到FIN包的server处于CLOSE_WAIT的状态。
  2. server发回一个ACK(值为client传过来的seq+1)和seq(值为client传过来的ack的值)给client。client收到server发过来的包后确认关闭连接,此时client处于FIN_WAIT_2。

第二阶段

  1. server在接收到client的FIN后,得知client要断开tcp连接了,于是在发送完ack和seq给client后,自己发送一个FIN包给client(也带有ack和seq包),告诉client我也要断开连接了,此时server处于LAST_ACK状态。
  2. client接收到server的FIN信息后,会回复server一个ack包,并且会进入TIME_WAIT状态,持续2个MSL(Max Segment Lifetime),这个时间windows下为240s。而server接收到client后便关闭连接。client在指定时间过后仍然没有接收到server的数据,确认server已经没有数据过来,也关闭了连接。

此时双方都进入CLOSED状态。

分析一下

server在接收到client的FIN后,会返回ACK给client,此时关闭的就是读通道,也就是说不能再从这个连接中读信息了。

client收到server发送过来的对自己的FIN的确认包ack后,便关闭了写通道,不能再向连接中写信息了。

server也开始关闭连接,发送FIN给client,而client收到后便回复ack给server,同时关闭读通道,自己则进入TIME_WAIT状态。

server收到client发送过来的对自己的FIN的确认包ack后,便关闭了写通道,状态转化为CLOSED。

而client在TIME_WAIT结束后也进入CLOSED状态。

因此client和server会经历如下状态的转移
client:
FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
server:
CLOSE_WAIT->LAST_ACK->CLOSED

其中有几个关键点需要注意:

  1. 这个TIME_WAIT的作用是什么?
    这个博客是这么解释的。

    原因有二:
    一、保证TCP协议的全双工连接能够可靠关闭
    二、保证这次连接的重复数据段从网络中消失 先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN。
    此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。
    这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。
    所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。 再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。
    一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair。
    于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。
  2. CLOSE_WAIT的解释。
    在以上事例,我们知道server在接收到FIN后,发送ACK之前会进入CLOSE_WAIT,如果长期处于这个状态,或者说服务器出现大量CLOSE_WAIT,说明ACK包一直没有发出,这时候就应该检查代码了。

  3. TIME_WAIT注意事项
    从事例我们知道,主动关闭连接的一方会经历TIME_WAIT状态,在该状态下的socket是不会被回收的。而如果是服务器端主动关闭连接,则可能会面临处于大量TIME_WAIT的情况(因为连接很多嘛),会严重影响服务器的处理能力。
    怎么解决呢,那就减少服务器端TIME_WAIT的时间咯。

综上所述,client和server从建立连接到断开连接,整个状态的变化如下:

client:
CLOSED->SYN_SEND->ESTABLISH->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
server:
CLOSED->LISTEN->SYN_RECV->ESTABLISH->CLOSE_WAIT->LAST_ACK->CLOSED

websocket

tcp是传输层的协议,tcp三次握手后,应用层协议http也便建立了连接。而对于当今web的发展情况,http仍有许多瓶颈。

  1. 一条连接只能发送一个请求。
  2. 请求只能从客户端开始。客户端不可以接收除响应以外的指令。
  3. 请求/响应首部未经压缩发送,首部信息越多延迟越大。
  4. 发送冗长的首部。每次互相发送相同的首部造成较多的浪费。
  5. 可任意选择数据压缩格式。非强制压缩发送。

虽然已经出现了很多解决方案,如ajax、comet,但是他们最终使用的都是http协议,因此也无法从根本上解决这些瓶颈。
因此也就诞生了一个新的通信协议,WebSocket协议,一种全双工通信协议。

该通信协议建立在http协议的基础之上,因此连接的发起方仍然是客户端,在http连接建立之后,再将协议升级为webSocket连接,在webSocket连接建立之后,客户度和服务器端都可以主动向对方发送报文信息了。

建立webSocket连接,需要先建立http连接,并在此基础上再进行一次”握手“。

client会发起一个”握手“的请求,请求首部含有upgrade:websocket(还有其他首部,具体看如下示例)。服务器端返回一个101状态码,确认转换协议。完成握手后便可以使用websocket协议进行通信。

Client(request)

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: AQIDBAUGBwgJCgsMDQ4PEC==
Origin: http://example.com
Sec-WebSocket-protocol: chat, superchat
Sec-WebSocket-Version: 13

Sec-WebSocket-Key其值采用base64编码的随机16字节长的字符序列,服务器端根据该域来判断client确实是websocket请求而不是冒充的,如http
Sec-WebSocket-protocol使用的子协议
Sec-WebSocket-Version该值必须是13

Server(response)

HTTP/1.1 101 switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat

Sec-WebSocket-Accept值是由client请求首部中的Sec-WebSocket-Key做SHA-1 hash计算,然后再把得到的结果通过base64加密而来

连接建立后,通信的url格式如下:
ws://example.com/
wss://example.com/

参考资料

    1. TCP的三次握手(建立连接)和四次挥手(关闭连接)
    2. 服务器TIME_WAIT和CLOSE_WAIT详解和解决办法

TCP连接建立与释放的更多相关文章

  1. 运输层协议:TCP连接建立与释放

    TCP的特点 面向连接:TCP是面向连接的运输层协议,通过TCP发送数据需要先建立连接,通信结束后需要释放连接 可靠传输:TCP实现了可靠传输,使得数据能够无丢失.无差错.不重复地到达接收端 面向字节 ...

  2. 计算机网络传输层之TCP协议(tcp协议特点、tcp报文段首部格式、tcp连接建立---三次握手、tcp连接释放---四次握手)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105516090 学习课程:<2019王道考研计算机网络> 学习目的 ...

  3. TCP传输连接建立与释放详解

    一直以来有许多读者朋友对TCP的传输连接建立和释放过程不是很理解,而这又是几乎网络认证中必考的知识点,包括软考.CCNA\CCNP.H3CNA\H3CNE等,为此再把笔者年度巨作,广受好评的——< ...

  4. 网络协议抓包分析——TCP传输控制协议(连接建立、释放)

    前言 TCP协议为数据提供可靠的端到端的传输,处理数据的顺序和错误恢复,保证数据能够到达其应到达的地方.TCP协议是面向连接的,在两台主机使用TCP协议进行通信之前,会先建立一个TCP连接(三次握手) ...

  5. TCP协议-连接建立和释放

    三次握手: (1)客户端向服务器端TCP请求连接,向服务器端发送控制位SYN=1,序号seq=x的请求报文.(x是随机产生的,且不能为0) (2)服务器端接收到请求报文后,若同意建立连接,则向客户端发 ...

  6. TCP 连接建立和断开,以及状态转换

    1. TCP报文结构 TCP是一种可靠.面向连接.全双工的传输层协议,其报文格式如下所示:      源端口.目的端口:16位长.标识出远端和本地的端口号.     顺序号:32位长.表明了发送的数据 ...

  7. TCP连接与释放

    TCP连接的建立 三次握手 TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态. TCP客户进程也是先创建传输控制块TCB,然后向服务器 ...

  8. TCP连接建立与关闭

    http://hi.baidu.com/psorqkxcsfbbghd/item/70f3bd91943b9248f14215cd TCP连接建立与关闭 TCP 是一个面向连接的协议,无论哪一方向另一 ...

  9. TCP连接建立和终止小结

    TCP连接建立(三次握手) 如图: 请求端发送一个SYN到服务器的相应端口,以及初始序号ISN 服务器发送包含服务器的初始序号的SYN作为应答,同时确认序号设置为客户的ISN+1 客户将确认序号设置为 ...

随机推荐

  1. 利用shell脚本批量提交网站404死链给百度

    网站运营人员对于死链这个概念一定不陌生,网站的一些数据删除或页面改版等都容易制造死链,影响用户体验不说,过多的死链还会影响到网站的整体权重或排名. 百度站长平台提供的死链提交工具,可将网站存在的死链( ...

  2. Android中使用Handler以及CountDownTimer实现包括倒计时的闪屏页面

    上一篇博文<Android中Handler使用浅析>通过实现倒计时闪屏页面的制作引出了Handler的用法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友能够点击链接回去看看 ...

  3. HTTP认证与https简介

    HTTP请求报头: Authorization HTTP响应报头: WWW-Authenticate  HTTP认证是基于质询/回应(challenge/response)的认证模式. HTTP认证 ...

  4. .Net Framework System.Collections 集合类

    本文内容 集合类 性能 最近复习了一下集合,C# 关于集合的类蛮多,但我除了 List 那几个经常用之外,其他的用得还真不多(只在小范围使用),但其实,每个集合类都各有自己适用的场景,功能也很强大.尤 ...

  5. Perl、PHP、Python、Java 和 Ruby 比较【转载+整理】

    从本文的内容上,写的时间比较早,而且有些术语我认为也不太准,有点口语化,但是意思到了. 问题: Perl.Python.Ruby 和 PHP 各自有何特点? 为什么动态语言多作为轻量级的解决方案? L ...

  6. JAVA 报错exe4j中this executable was created with an evaluation 怎么办

    如果使用未破解注册的exe4j打包JAR文件为EXE,运行EXE的时候就会出现下面的提示   打开exe4j软件,Change License或者是输入序列号,然后用注册机算一个注册码即可  

  7. tomcat重启后session没有清除的解决办法

    tomcat的默认设置是:用户保存的session信息会持久到到硬盘中,即使重启tomcat,这些session信息也不会丢失. 如果希望重启tomcat,清除所有session信息,可以修改tomc ...

  8. Android 之 assets目录和raw目录

    Android 中存在assets目录和raw目录,它们既有相似之处又有所不同.一.共同点: 目录下的资源会被原封不动的拷贝到APK中,而不会像其它资源文件那样被编译成二进制的形式. 二.区别 1.最 ...

  9. [转]double与BigDecimal

    转自:http://superivan.iteye.com/blog/963628 [1] 精确的浮点运算: 在Java里面,有时候为了保证数值的准确性需要精确的数据,先提供一个例子就可以发现问题了: ...

  10. 透彻理解Ioc

    引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...