一、tcp协议格式





二、三次握手


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

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

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

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

通过这种

url=eZXiFRQOKsO6NUMErlv_ourWMexrPfxtUhSw1f5waWf_gVDDeOpI7xFga2VygpC-qZWFVkj-XTcQeKx7UQO7fq" style="color:rgb(202,0,0); text-decoration:none">三次握手。client与服务端建立起可靠的双工的连接,開始传送数据。 三次握手的最主要目的是保证连接是双工的,可靠很多其它的是通过重传机制来保证的。可是为什么一定要进行三次握手来保证连接是双工的呢。一次不行么?两次不行么?

我们举一个现实生活中两个人进行语言沟通的样例来模拟

url=eZXiFRQOKsO6NUMErlv_ourWMexrPfxtUhSw1f5waWf_gVDDeOpI7xFga2VygpC-qZWFVkj-XTcQeKx7UQO7fq" style="color:rgb(202,0,0); text-decoration:none">三次握手

第一次对话: 

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

结果乙带着耳机听歌呢。根本没听到,没反应。

甲心里想:跟你说话也没个音,不跟你说了,沟通失败。说明乙接受不到甲传过来的信息的情况下沟通肯定是失败的。

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

第二次对话: 

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

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

通过前两次对话证明了乙可以听懂甲说的话,而且能做出正确的应答。

接下来进行第三次对话。

第三次对话:

甲刚和乙打了个招呼,突然老婆喊他。“你个死鬼,打个酱油咋这么半天,看我回家咋收拾你”,甲是个妻管严,听完吓得二话不说就跑回家了,把乙自己晾那了。

乙心想:这什么人啊,得,我也回家吧,沟通失败。说明甲无法做出应答的情况下沟通失败。

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

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

同理对于TCP为什么须要进行三次握手我们能够一样的理解:

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

三、四次挥手

url=8_DsYi4pjWpNRFrSX10jiGxe0PLruypbRhv4o56eXOi07tQPokeFgnt1_leXVDy7ELc-uR4_E1cr1NfV3lJUYK" style="color:rgb(202,0,0); text-decoration:none">因为
TCP 连接是全双工的。因此每一个方向都必须单独进行关闭
。这好比,我们打电话(全双工),正常的情况下(出于礼貌),通话的两方都要说再见后才干挂电话,保证通信两方都把话说完了才挂电话

TCP
的四次握手
是为了保证通信两方都关闭了连接,详细步骤例如以下:

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

2)server B
底层收到clientA的FIN时会做两件事

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

2.2)第2件事:收到clientA的FIN时。导致serverB的应用层read()返回0(告诉serverB应用层:clientA关闭了)

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

4)client A
底层回发 ACK(tcp协议中ACK位置1,确认序号N+1) 给serverB,这是clientA、serverB都处于全然关闭状态。回收对应的资源。

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



这是由于服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后,它能够把 ACK 和 SYN(ACK 起应答作用。而 SYN 起同步作用)放在一个报文里来发送。

但关闭连接时,当收到FIN
报文通知时,假设能将ACK、FIN放在一个报文里那么就有了三次挥手。可是这是不可能。由于ACK是serverB一收到FIN报文底层就回发的,而serverB的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. 浅谈TCP三次握手和四次挥手

    学习三次握手和四次挥手前,先了解下几个基础的概念. Seq:数据段序号,我们都知道TCP是提供有序传输的,有序传输的基础就是数据段序号,接收方在收到发送方乱序包的情况下可以根据Seq进行重新排序,确保 ...

  2. Linux网络编程一、tcp三次握手,四次挥手

    一.TCP报文格式 (图片来源网络) SYN:请求建立连接标志位 ACK:应答标志位 FIN:断开连接标志位 二.三次握手,数据传输,四次挥手 (流程图,图片来源于网络) (tcp状态转换图,图片来源 ...

  3. Linux运维学习笔记-TCP三次握手和四次挥手

    TCP三次握手:     TCP四次挥手:

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

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...

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

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  6. 网络编程之TCP三次握手与四次挥手、基于TCP协议的套接字编程

    目录 TCP三次握手和四次挥手 背景描述 常用的熟知端口号 TCP概述 TCP连接的建立(三次握手) TCP四次挥手 如果已建立连接,客户端突然断开,会怎么办呢? 基于TCP协议的套接字编程 什么是S ...

  7. 网络编程-tcp三次握手和四次挥手

    TCP三次握手和四次挥手过程 1.三次握手 (1)三次握手的详述 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Client端接收到ACK报文后也向 ...

  8. 浅谈浏览器解析 URL+DNS 域名解析+TCP 三次握手与四次挥手+浏览器渲染页面

    (1)浏览器解析 URL 为了能让我们的知识层面看起来更有深度,我们应该考虑下面两个问题了: 从浏览器输入 URL 到渲染成功的过程中,究竟发生了什么? 浏览器渲染过程中,发生了什么,是不是也有重绘与 ...

  9. 应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题

    重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供 ...

随机推荐

  1. SS配置,Brook是什么?,Brook如何配置(Android篇)

    很长时间没有更新了,今天给大家分享一下什么是Brook,和SS有什么区别?写的不好,请勿见外,大佬绕过. Brook简单介绍 Brook 是一个高效的 Socks5 代理软件,官方支持Windows. ...

  2. 【TIDB】1、TiDb简介

    一 TiDb简介 TiDB 是 PingCAP 公司受 Google Spanner / F1 论文启发而设计的开源分布式 HTAP (Hybrid Transactional and Analyti ...

  3. NetCore Netty 框架 BT.Netty.RPC 系列随讲 二 WHO AM I 之 NETTY/NETTY 与 网络通讯 IO 模型之关系?

    一:NETTY 是什么? Netty 是什么?  这个问题其实百度上一搜一堆. 这是官方话的描述:Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个 ...

  4. centos语言设置

    . echo $LANG可以查看当前使用的系统语言 . 在终端输入 locale命令,如有zh cn 表示已经安装了中文 . 安装中文语言包yum groupinstall chinese-suppo ...

  5. ACM_开挂的小G

    开挂的小G Time Limit: 2000/1000ms (Java/Others) Problem Description: 小G寒假在家没网络,闲着没事干又看不下书,就玩起了单机游戏ACM_Ga ...

  6. hbuilder中的 http://www.w3.org/TR/html4/strict.dtd

    <!-- This is HTML 4.01 Strict DTD, which excludes the presentation attributes and elements that W ...

  7. phpstorm如何配置xdebug?(hpStudy+PhpStorm+XDebug配置)

    xdebug是什么? 初次接触,反复试了几次终于把这个xdebug给搞清楚了,类似于前端的控制台这样的东西,可以根据断点展示我们想要看的数据. 如何配置xdebug? 配置前说明: 1.phpStud ...

  8. [Android]异常7-Error:Configuration with name 'default' not found.

    背景:使用SVN更新代码,运行出现 异常原因: 可能一>缺少Modules 解决办法有: 解决一>Android Studio切换为Project,settings.gradle中引用和现 ...

  9. java与javascript之间json格式数据互转

    javascript中对象与字符串的互转 对象转为字符串:通过JSON.encode方法,这个是json.js里面的方法,引入到当前文件就可以了. 字符串转换为对象:①使用JSON.decode方法, ...

  10. CSS中的disable,hidden,readonly

    项目中有时候需要对某个input进行隐藏或者禁止修改等. 需要隐藏某个input的时候就用hidden <input hidden="true" > 如果要禁止修改in ...