TCP三次握手原理

在众多的网络协议中,TCP协议占据着举足轻重的地位,你知道什么是TCP协议吗?编程

1、TCP协议

TCP(Transmission Control Protoco)协议属于计算机网络体系中的运输层。运输层的任务是负责向主机中应用层进程之间的通讯提供通用的数据传输服务。因此能够通俗理解TCP协议就是进程间数据通信传输协议。根据不一样应用,运输层主要使用TCP和UDP两种协议之一。若是想要了解计算机网络体系分层概念,能够看个人上一篇博文 计算机网络体系结构划分 缓存

计算机网络体系结构

2、TCP协议特色

TCP协议自己是比较复杂的,它包含拥塞控制、可靠传输、流量控制、链接管理等功能,主要特色包含如下几个方面:服务器

  • TCP是面向链接的协议,程序在使用TCP协议通信时,必需要先创建TCP链接。这就比如我要给你打电话,咱俩之间的通信线路必须是链接状态的。
  • TCP链接是点对点的,每一条TCP链接只能有两个端口(endpoint)。这个端点就是咱们Java网络编程所使用的套接字(socket)。由IP地址+端口号组成(IP:端口号)。
  • TCP链接提供可靠交付,也就是说使用TCP链接传输数据,保证无差错、不丢失、不重复而且按顺序到达
  • TCP链接是双向的通讯,也就是说通讯的两方,既能发送数据,也能接收数据。就向咱们通话时双方同样。
  • TCP面向字节流传输数据,就是说TCP传送数据时,是把进程交付的数据,按照一段段字节流序列传递的,每次传输其中一段字节序列。应用层接收字节序列后,再将内容还原。

3、TCP报文格式

既然TCP协议属于运输层,运输层职责是为主机应用层提供进程间的数据传输,因此咱们有必要搞清楚TCP协议运输数据时的形式。TCP协议规定了TCP传输数据的单元为TCP数据报。TCP报文是对应用层进程交付数据的封装。 TCP数据报由两部分组成:TCP首部TCP数据部分网络

  • TCP首部:包含许多控制和描述字段,是TCP所有功能的体现
  • TCP数据部分:对于应用层进程交付的数据,封装后的字节流序列
    TCP报文格式
    应用层进程交付的数据被封装TCP报文,而后进行传输,TCP链接保证数据传输的可靠性,TCP报文传输的过程示意图:
    TCP数据传输模型

4、TCP报文首部

TCP报文首部定义是TCP协议的精华所在,TCP复杂功能的实现,所有依靠了首部里各类控制字段。咱们来看下TCP首部都定义了什么: socket

TCP报文首部
TCP报文的首部 由20个字节固定字节4n(n取[0~5]整数)个可变的 选项字节组成,其中固定部分的各字段含义以下:

  • 源端口目的端口:各占2个字节,分别写入通讯双方进程端口号post

  • 序号seq:占4个字节。在TCP链接中,传送的字节流中的每个字节都是要按顺序编号[0~2^32^-1],整个要传送的字节流的起始序号在必须链接创建时设置,序号字段值表明本报文段所发送的数据的第一个字节的序号计算机网络

  • 确认号ack:占4个字节,是指望收到对方的下一个报文段的第一个数据字节的序号,即ack=N,就表明了到序号N-1为止的全部数据都被正确接收了。指针

  • 数据偏移:占4位,表示TCP报文的数据部分起始处距离TCP报文首部的起始处有多远,数据偏移值的单位是32位字(以4字节为计算单位),4位二进制能表示的值[0~15],这就意味着TCP首部最大长度为60字节,也就是选项部分的最大长度为40字节。cdn

  • 保留位:占6位,保留为之后使用,目前置为0server

  • 控制位:占6位,每一个控制字段占1位,它们的标识和含义是:

    • 紧急URG:URG=1时,告诉系统此报文中有紧急数据,优先传送,与紧急指针配合使用
    • 确认ACK:当ACK=1时,确认号才有效,ACK=0时,确认号无效,TCP链接创建后,全部报文ACK必须都为1
    • 推送PSH:发送方把PSH置为1,接收方收到报文后会尽快交付,不用等缓存填满了再交付
    • 复位RST:当RST=1时,代表TCP链接出现了严重差错,必须释放链接,而后从新创建新运输链接。RST=1还能够用来拒接一个非法报文段或拒绝打开一个链接。
    • 同步SYN:在链接创建时用来同步序号。当SYN=1而ACK=0时,代表这是一个链接请求报文段,对方若赞成创建链接,则须要在响应报文中使SYN=1和ACK=1
    • 终止FIN:用来释放一个链接 。当FIN=1时,代表此报文段的发送方数据已经发送完毕,而且要求释放运输链接。
  • 窗口:占2字节,窗口值是[0~2^16^-1]之间的整数。窗口值告诉了对方,从本报文段的确认号算起,容许对方发送的数据量。

  • 检验和:占2字节,用于接收方检验首部和数据部分是否在传输中有差错,相似咱们下载文件时的Md5签名校验做用。

  • 紧急指针:占2字节,URG=1时才起做用,用于指明本报文段中的紧急数据的字节数,紧急数据结束后就是普通数据,因此紧急指针指出了紧急数据的末尾在报文中位置。

  • 选项:长度可变,最小0字节,最长达40字节。首部用来动态存储数据。

5、三次握手过程

TCP是面向链接的,因此每次传输数据以前,必需要创建TCP链接,在TCP创建链接时主要解决三个层面问题:

  • 使链接的每一方都能确认对方的存在
  • 协商链接中参数,好比各方窗口值,时间戳等
  • 各方对运输资源如缓存大小、链接表等进行分配

咱们都知道TCP链接采用的是C/S模式,主动发起链接的叫客户端client,被动等待链接的叫服务器Server。那么TCP创建链接的过程是什样的呢?什么是三次握手呢?

在这里插入图片描述
默认状况下客户端client和服务端sever的TCP进程都处于 CLOSED(关闭)状态。 服务端TCP服务进程先创建传输控制块TCB,而后准备接受客户端请求,此时服务端进入 LISTEN状态,等待客户端链接请求,

  • 第一次握手:客户端TCP进程也先创建传输控制块TCB,而后向服务端发送链接请求报文段,此时SYN=1,随机选定一个初始序号seq=x,,此报文不能携带数据,可是要消耗掉一个序号,发送完毕后,客户端进入SYN-SENT(同步已发送)状态
  • 第二次握手:服务端收到客户端请求链接报文段后,若赞成创建链接,则发送确认报文,确认报文中SYN=一、ACK=1,确认号ack=x+1,同时随机选定一个本身序号seq=y,确认报文段一样不能携带数据,可是也要消耗掉一个序号,发送完毕后服务端进入SYN-RCVD(同步收到)状态
  • 第三次握手:客户端收到确认报文后,检查ACK=1,ack=x+1是否正确,若正确,则向服务端发送确认报文,确认报文中ACK=1,ack=y+1,seq=x+1,发送后进入ESTAB-LISHED状态,服务端收到确认报文后,也进入ESTAB-LISHED状态,此时双方TCP链接正式创建。

上面的链接创建过程就是TCP三次握手

6、为何是三次握手?

为何client收到确认报文后,还要再发送一次确认报文给server呢?这主要是为了防止已失效的链接请求报文段忽然又送到了Server端。

假设如今TCP链接是两次握手机制,以下图server在收到client的链接请求,确认后就进入ESTAB-LISHED状态,会存在这样一种问题:

client发送链接请求报文,因为网络缘由,长时间阻塞在某个网络节点上了,因而client重传了一次请求链接报文,第二次请求报文正常达到server,链接正常创建,数据传输完毕后,释放链接。

可是假设此时第一次发送的请求报文并无丢失,而是延误一段时间才到达server,这本是已失效的链接请求报文段,可是server收到后,会觉得是client从新发送的链接请求,因而向client发送确认报文后,进入ESTAB-LISHED状态,可是client并无发出新建链接的请求,就会忽略server的确认报文,server却在一直等待client发送数据,致使server资源浪费严重。

两次握手
总结起来看,TCP三次握手过程就是client与server在相互确认各自发送和接收是否正常的过程:

  • 第一次握手:client—>server,server确认了cilent的发送能力和本身的接收能力是正常的
  • 第二次握手:server—>client,client确认了本身的发送能力和server的接收能力是正常的,可是server此时不清楚本身的发送能力是否正常
  • 第三次握手:client—>server,server确认了本身的发送能力正常,同时也代表双方也都确认完毕,能够开始传输数据。

那么为何不进行四次握手呢?这个问题留给大家解答。

相关文章
相关标签/搜索