TCP是面向连接的协议,其数据传输过程分为建立连接、数据传送、释放连接三个阶段。

0 建立连接

建立连接的过程也就是常说的“三次握手”:

  • 客户端向服务器端发送一个SYN报文(SYN=1表示这是一个连接请求或连接接收报文),并随机选取一个起始序号x;
  • 服务器端应答一个SYN报文,同时ACK(确认位)置1【ACK=1时TCP报文段首部中的ack(确认号字段)才有效】,随机选取一个服务器端的起始序号y,并将ack字段设为x+1,表示已经收到客户端发来的SYN报文,期待收到序号为x+1的下一个报文;
  • 客户端应答一个ACK报文,将序号设为x+1,并且ack字段设为y+1,表示已经收到服务器端的SYN报文,期待收到序号为y+1的下一个报文。

    注:序列号seq也称ISN(Initial Sequence Number)



    之所以要采用三次握手机制而不是两次或四次,要从握手机制的目的说起:

    握手主要是为了确认双方的发送、接收能力是否正常,顺带初始化序号seq,为以后的数据传送做好准备,所以:

    第一次握手:服务器收到客户端发来的网络包,服务器就明白客户端的发送能力、服务器的接收能力正常;

    第二次握手:服务器发包,客户端收到后,客户端就明白服务器的发送、接收,客户端的发送、接收都是正常的;

    二次握手后,客户端倒是全明白了,但是服务器端无法确认客户端能否正常接收、服务器是否正常发送,所以两次握手不够;

    第三次握手:服务器收到客户端发送的网络包,服务器确认了自己上次的发送正常、客户端接收也正常,所以四次握手是多余的。

1 补充问题

  • 序列号(ISN)之所以随机生成,是为了避免被攻击(若固定,则下一次传送的ack就显而易见);
  • 前两次握手不可以携带数据,第三次可以携带。第一次握手服务器端接收能力未知,如果携带数据就可能丢失。第二次客户端接收能力未知,如果携带数据也可能丢失。第三次客户端知道服务器接收正常,并且自己已经处于ESTABLISHED状态;
  • 服务器发出SYN报文后,处于SYN-RCVD状态,此时不同的连接请求会被放在半连接队列里,三次握手完成后的连接请求被放在全连接队列里。

2 连接释放

连接释放的过程也就是常说的“四次挥手”:

P.S. 图中以客户端发起释放请求为例

  1. 客户端发送释放请求,将FIN(终止位)置1,表示客户端已经发完数据,请求释放;
  2. 服务器发一个ACK报文,确认号ack为u+1,这时从客户端到服务器的连接被释放,处于半关闭状态
  3. 如果服务器也要断开连接,就向客户端发送连接释放报文(FIN=1);
  4. 客户端发送一个应答报文,序列号seq为u+1,等待一段时间(2MSL)确保服务器收到ACK报文,之后关闭连接。



客户端之所以要等待2MSL时间才关闭,有两个原因:

  • 一旦服务器没有收到ACK报文,服务器就会重发FIN报文,客户端再次收到FIN报文,就知道之前发送的ACK报文丢失,会重置时间等待计时器为2MSL并重传ACK报文。

    如果没有这段等待时间,万一服务器没有正常接收ACK报文,接下来重传的FIN报文段就无法到达客户端,服务器无法正常关闭。
  • 客户端发完最后一个ACK报文,经过2MSL,本次连接产生的报文都会从网络中消失,避免下一次新连接出现本次旧的连接请求报文段。

TCP 3-Way Handshake的更多相关文章

  1. TCP Connection Establishment and Termination

    Three-Way Handshake The following scenario occurs when a TCP connection is established: The server m ...

  2. 基于TCP协议的网络通讯流程

    不多说了,先上个图: 从上面的图中可以看出来,基于TCP协议进行通讯可以大致分成以下几个阶段: 1. 首先是在服务器端, TCP Sever调用socket(), bind(), listen()完成 ...

  3. FW 常见的性能测试工具有: loadRunner/netperf/httperf/apache_ab/Apache JMeter

    常见的性能测试工具有: loadRunner/netperf/httperf/apache_ab/Apache JMeter , 其中loadRunner属于付费软件,所以在这里不做介绍 netper ...

  4. 内网内使用https 和 使用http 建立连接的速度对比

    文字版 使用https httpstat https://10.24.101.14/cwbase/web/Login.aspx --insecure Connected to HTTP/ OK Ser ...

  5. httpstat的简单使用

    httpstat 应该是一个 python 封装后的 curl 工具能够展现 一些客户端连接网站的时间消耗,最近在看tls 感觉挺有用处的 简单学习一下 1. centos7 安装python 和 p ...

  6. The POSIX API/nss/nscd

    https://code.google.com/p/nsscache/wiki/BackgroundOnNameServiceSwitch The POSIX API POSIX is a stand ...

  7. The TCP three-way handshake (connect)/four wave (closed)

    TCP, relative to the SOCKET developers create process and link remove process consists of the TCP/IP ...

  8. TCP Three-way Handshake

    TCP Connection Management Out-of-Order and Duplication(复制) Problem Old segment from previous connect ...

  9. TCP 3-Way Handshake (SYN,SYN-ACK,ACK)

    http://www.inetdaemon.com/tutorials/internet/tcp/3-way_handshake.shtml

随机推荐

  1. 【数据库】MySQL数据库(二)

    一.数据库文件的导出 1.在DOS命令行下导出数据库(带数据) mysqldump -u root -p 数据库名 > E:\wamp\www\lamp175\lamp175.sql 2.在DO ...

  2. Linux 系统篇(一)

    退出当前程序    quit 填充代码:    tab键 中断当前操作:    ctrl + c 键盘输入结束    ctrl + d 关机        shutdown 重启        reb ...

  3. Array(数组)对象-->slice() 方法

    1.定义和用法 slice()方法可提取字符串的某个部分,并以新的字符串返回被提取的部分. 语法: array.slice(start, end) 参数:start 开始元素的下标,截取内容包含该元素 ...

  4. Python爬虫系列(一):从零开始,安装环境

    在上一个系列,我们学会使用rabbitmq.本来接着是把公司的celery分享出来,但是定睛一看,celery4.0已经不再支持Windows.公司也逐步放弃了服役多年的celery项目.恰好,公司找 ...

  5. leetcode c++做题思路和题解(5)——堆的例题和总结

    堆和优先队列 堆的简介, 是一种二叉树, 有最大堆和最小堆miniheap. 通常用于构建优先队列. 0. 目录 数据流中的第K大元素 1. 数据流中的第K大元素 数据流中的第K大元素 复杂度为log ...

  6. awk线程号

    for i in `ps|grep [a]out|awk '{print $1}'` do kill -9 "$i" done

  7. 一文回顾Reids五大对象(数据类型)

    Redis 是一个高性能的分布式内存型数据库,在国内外各大互联网公司中都有着广泛的使用,即使是一些非互联网公司中也有着非常重要的适用场景,所以对 Redis 的掌握也成为后端工程师必备的基础技能,在面 ...

  8. 数据结构与算法--树(tree)结构

    树 二叉树 遍历原则:前序遍历是根左右, 中序遍历是左根右,后序遍历是左右根. 二叉搜索树 特点:对于树中的每个节点X,它的左子树中所有节点的值都小于X,右子树中所有节点的值都大于X. 遍历:采取二叉 ...

  9. 包、mode模式、if-else语句、switch语句

    目录 包 mode模式 if-else语句 循环 switch语句 包 //1 在同一个包下(文件夹下),包名必须一致 //2 以后,包名就是文件夹的名字 //3 同一个包下,同名函数只能有一个(in ...

  10. webform repeater 的使用

    1  repeater    定义: 重复器    根据数据库里的内容将repeater里的内容重复赋值 ,在itemtemplate下   配合<%# Eval(" ") ...