一、tcp协议格式

二、三次握手

在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。

第一次握手:建立连接时,客户端发送 syn 包(tcp协议中syn位置1,序号为J)到服务器,并进入 SYN_SEND 状态,等待服务器确认;

第二次握手:服务器收到 syn 包,必须确认客户的 SYN,同时自己也发送一个 SYN 包,即 SYN+ACK包(tcp协议中syn位置1,ack位置1,序号K,确定序号为J+1),此时服务器进入 SYN_RECV 状态;

第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(tcp协议中ack位置1,确认序号K+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。

通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。 三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。但是为什么一定要进行三次握手来保证连接是双工的呢,一次不行么?两次不行么?

我们举一个现实生活中两个人进行语言沟通的例子来模拟三次握手。

第一次对话: 

老婆让甲出去打酱油,半路碰到一个朋友乙,甲问了一句:哥们你吃饭了么?

结果乙带着耳机听歌呢,根本没听到,没反应。甲心里想:跟你说话也没个音,不跟你说了,沟通失败。说明乙接受不到甲传过来的信息的情况下沟通肯定是失败的。

如果乙听到了甲说的话,那么第一次对话成功,接下来进行第二次对话。

第二次对话: 

乙听到了甲说的话,但是他是老外,中文不好,不知道甲说的啥意思也不知道怎样回答,于是随便回答了一句学过的中文 :我去厕所了。甲一听立刻笑喷了,“去厕所吃饭”?道不同不相为谋,离你远点吧,沟通失败。说明乙无法做出正确应答的情况下沟通失败。

如果乙听到了甲的话,做出了正确的应答,并且还进行了反问:我吃饭了,你呢?那么第二次握手成功。

通过前两次对话证明了乙能够听懂甲说的话,并且能做出正确的应答。接下来进行第三次对话。

第三次对话:

甲刚和乙打了个招呼,突然老婆喊他,“你个死鬼,打个酱油咋这么半天,看我回家咋收拾你”,甲是个妻管严,听完吓得二话不说就跑回家了,把乙自己晾那了。乙心想:这什么人啊,得,我也回家吧,沟通失败。说明甲无法做出应答的情况下沟通失败。

如果甲也做出了正确的应答:我也吃了。那么第三次对话成功,两人已经建立起了顺畅的沟通渠道,接下来开始持续的聊天。

通过第二次和第三次的对话证明了甲能够听懂乙说的话,并且能做出正确的应答。 可见,两个人进行有效的语言沟通,这三次对话的过程是必须的。

同理对于TCP为什么需要进行三次握手我们可以一样的理解:

为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

三、四次挥手

由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这好比,我们打电话(全双工),正常的情况下(出于礼貌),通话的双方都要说再见后才能挂电话,保证通信双方都把话说完了才挂电话

那TCP 的四次握手,是为了保证通信双方都关闭了连接,具体过程如下:

1)客户端 A 在应用层调用close时会激发底层发送一个 FIN(tcp协议中FIN位置1、序号为M,结合上图分析)请求,用来关闭客户 A 到服务器 B 的数据传送,客户端A此时处于半关闭状态(应用层无法接收数据但底层还可以接收数据);

2)服务器 B 底层收到客户端A的FIN时会做两件事

2.1)第1件事:收到客户端A的FIN时底层会主动回发一个ACK(tcp协议中ACK位置1,确认序号M+1)

2.2)第2件事:收到客户端A的FIN时,导致服务器B的应用层read()返回0(告诉服务器B应用层:客户端A关闭了)

3)服务器B应用层调用close()激发底层给客户端 A 发送一个 FIN(tcp协议中FIN位置1、序号为N),这是服务器B已处于半关闭状态;

4)客户端 A 底层回发 ACK(tcp协议中ACK位置1,确认序号N+1) 给服务器B,这是客户端A、服务器B都处于完全关闭状态,回收相应的资源。

为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?


这是因为服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后,它可以把 ACK 和 SYN(ACK 起应答作用,而 SYN 起同步作用)放在一个报文里来发送。但关闭连接时,当收到FIN 报文通知时,如果能将ACK、FIN放在一个报文里那么就有了三次挥手,但是这是不可能,因为ACK是服务器B一收到FIN报文底层就回发的,而服务器B的FIN是应用层调用close()激发的,所以它这里的 ACK 报文和 FIN 报文在发送的时间上都是分开的,不可能同时发送。

为什么 TIME_WAIT 状态还需要等 2MS L后才能返回到 CLOSED 状态?


这是因为虽然双方都同意关闭连接了,而且握手的 4 个报文也都协调和发送完毕,按理可以直接回到 CLOSED 状态(就好比从 SYN_SEND 状态到 ESTABLISH 状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的 ACK 报文会一定被对方收到,因此对方处于 LAST_ACK 状态下的 SOCKET 可能会因为超时未收到 ACK 报文,而重发 FIN 报文,所以这个 TIME_WAIT 状态的作用就是用来重发可能丢失的 ACK 报文。(里面涉及的状态是什么意思,详情请看《TCP 通信过程中各步骤的状态》)

Linux网络编程——浅谈 TCP 三次握手和四次挥手相关推荐

  1. 【Linux网络编程】浅谈 TCP 三次握手和四次挥手

    三次握手 在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND 状态,等 ...

  2. 网络编程知识预备(2) —— 三次握手与四次挥手、半连接状态、2MSL

    参考:网络编程知识预备(2) --三次握手与四次挥手.流量控制(滑动窗口).拥塞控制.半连接状态.2MSL_行稳方能走远的博客-CSDN博客 目录 一.三次握手 什么是三次握手? 三次握手图解 三次握 ...

  3. 【java网络编程】TCP三次握手、四次挥手,常见Socket通信BIO

    网络编程,网络通信 内容管理 TCP三次握手,四次挥手 TCP 建立连接 --- 三次握手 TCP断开 ---- 四次挥手 java网络IO BIO 同步阻塞 Socket通信模型 BIO网络通信De ...

  4. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    转自即时通讯网:http://www.52im.net/ 1.引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道"三次"和&quo ...

  5. 网络协议-网络分层、TCP/UDP、TCP三次握手和四次挥手

    网络的五层划分是什么? 应用层,常见协议:HTTP.FTP 传输层,常见协议:TCP.UDP 网络层,常见协议:IP 链路层 物理层 TCP 和 UDP 的区别是什么 TCP/UDP 都属于传输层的协 ...

  6. 网络 -- TCP三次握手和四次挥手

    1.TCP三次握手和四次挥手过程发生在TCP的"连接管理机制"中 2.先介绍一下在三次握手和四次挥手过程中需要用到的三个标志位: SYN: 请求建立连接; 双方都需要建立连接 AC ...

  7. Node 学习八、通信之 01 网络通信基本原理、网络层次模型、数据封装与解封装、TCP三次握手与四次挥手

    网络通信基本原理 网络通信(或通讯)模型和通讯协议(常见的 HTTP.TCP/IP.FTP等)解决的本质问题就是主机与主机之间的网络通信. 下面以最基本的两台主机之间的通信开始,慢慢认识网络通信模型和 ...

  8. 硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

    来自:小林coding 每日一句英语学习,每天进步一点点: 前言 不管面试 Java .C/C++.Python 等开发岗位, TCP 的知识点可以说是的必问的了. 任 TCP 虐我千百遍,我仍待 T ...

  9. 图解TCP三次握手和四次挥手!(简单易懂)

    哈喽:亲爱的小伙伴,首先祝大家五一快乐~ 本来打算节日 happy 一下就不发文了,但想到有些小伙伴可能因为疫情的原因没出去玩,或者劳逸结合偶尔刷刷公众号,所以今天就诈尸更新一篇干货,给大家解解闷~ ...

最新文章

  1. oracle rman imp exp,Oracle-client支持exp|imp|rman
  2. c语言file_C语言 技能提升 系列文章(七)格式化输入/输出
  3. java timer 线程安全_多线程之 线程安全与控制
  4. brew php7 intl_brew安装php7
  5. 【C++、Matlab】VS2013 C++读写.mat文件
  6. android中Intent的一些用法和总结
  7. 平凡的故事:年轻开发者的那些伤心事
  8. linux 编译条件检查,如何利用GCC编译选项检测栈溢出
  9. 沙普利算法java实现_Java实现婚姻稳定匹配Gale- Shapley算法
  10. 什么是Windows安全模式?Windows安全模式详解
  11. X1000代码烧写配置
  12. 电路分析 基础 电容和电感元件
  13. Fatal error: Failed to identify device. Check connections and/or resethardware
  14. 【用PROTEUS仿真点亮LED项目】
  15. android高仿微信的图片查看
  16. MockFlow线框图、原型软件
  17. 第五人格服务器维护中请稍后登录,第五人格:国际服维护重大故障,刚开精华二,却登录不了游戏...
  18. WebRTC Trickle ICE 策略
  19. linux 文件格式elf,linux ELF 文件格式 | ZION
  20. The Biggest Water Problem—每日算法档

热门文章

  1. debian编译mysql_MySQL数据库之Debian 6.02下编译安装 MySQL 5.5的方法
  2. python输出二进制数_二进制中1的个数(python)
  3. 小游戏_猜数_JAVA
  4. 分数加减法_JAVA
  5. CNN应用之SPP(基于空间金字塔池化的卷积神经网络物体检测)-ECCV 2014-未完待续
  6. 10道C++输出易错笔试题收集(敢进来挑战吗?)
  7. 重入锁:ReentrantLock 详解
  8. ThreadLocal源码剖析
  9. alibaba JSON TypeReference 复杂类型转换
  10. Thinking in java基础之集合框架