前言:


  1. TCP协议是计算机的基础,他本身是一个非常非常复杂的协议。
  2. 本文只是蜻蜓点水,将从网络基础以及TCP的相关概念介绍开始,之后再将三次握手,四次挥手这些内容来阐述。
  3. 最后介绍一些常见问题,并给出解答。

网络分层


在实际的网络中,我们是四层网络结构:

网络传输层

网络传输层负责最底层的底层链路连接。两台主机之间进行互联,基于网线的物理硬件上的协议。在这个侧面,主机与主机之间只认得硬件mac编码。并不认识IP。

网络层

IP就是在网络层出现的,就像网络上,每个机器的地址。网络层可以理解为快递,它的职能就是根据地址(IP),把东西从一个地方运送到另一个地方

传输层

传输层相比于网络层最大的不同就是引入了端口的概念。网络层只管发送地址和目的地址。但是发送主机上有可能有多个程序和同一个接收主机进行传输数据,怎么区分这多个程序呢?就引入了端口的概念。(发送IP地址,发送端口,接收IP地址,接收端口)四元组标示了一个主机的程序到另一个主机程序的唯一标示。传输层的职能,就是维护这个四元组。

其实传输层还有一个职能是定义发送方和接收方基本处理包的行为。上面说到网络层就相当于邮件运输工,它只负责把一包东西从一个地方放到另外一个地方,但是,这包东西是否送达了,送达之后接收方又有什么行为。这些都可以在传输层进行定义。注意,这里说的是可以,你也可以在传输层布不管这些,只做简单的基本封装四元组,比如UDP

应用层

指定到主机端口了,接下来就是应用层干活了,可以传文件,传文本。应用层就是实际上对具体的程序之间的交互功能进行定义的层。

TCP协议


TCP(Transmission Control Protocol) 传输控制协议.TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接。

协议结构如下:

这里就不全部都讲了,主介绍一部分:

Source Port和Destination Port

这两个字段表示发送地址和目的地址的端口号,发送地址的IP和目的地址的IP是在IP协议头中

Sequence number(顺序号码) Acknowledge number(确认号码)

TCP的任意一端(不管是客户端还是服务端),可以发送数据,也可以接受数据。那么发送序列号就是Seqence Number,接受序列号就是Acknowledgement Number。

其次,序列号是用来标志包的顺序的。网络中包由于网络问题,接受到的并不是按顺序到达的,接受端可以根据这个序列号来进行组装。

比如:

给服务端发送8000字节的数据,顺序号从10000开始,分成4个包发送,那么它们的标识就是12000,14000,16000,18000。

如下图所示,由于网络问题,最先到达的是序号为14000,但是服务端可以根据这些包的序号进行拼接,拼成完整的包。

Data offset和Reserved

由于tcp头可能是不固定大小的(因为存在可选字段),所以需要有这个值来表示当前这个包的tcp头有多大。

Reserved就是保留字段

位码TCP标志位

就是下图中的红框的内容

SYN(synchronous建立联机):建立连接,发送一方告知另外一方,请求建立连接

ACK(acknowledgement 确认):该包中有回复信息

PSH(push传送):该包中有传输信息

FIN(finish结束):结束位,发送一方告知另外一方,请求中断连接

RST(reset重置):重置位,这个包是用来要对方重置连接

URG(urgent紧急):紧急位,已经建议弃用

 

握手与挥手:


有了上面的基础知识,相信下面的三次挥手和四次握手理解起来也不会费劲的。

下图是三次握手的过程:

三次握手过程说明:

TCP服务器进程先创建传输控制块TCB(存储了每一个连接中的一些重要信息,如:TCP连接表,到发送和接收缓存的指针,到重传队列的指针,当前的发送和接收序号,等),准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。如有,即作出相应。

第一次握手:

客户端Client向服务端Server发起建立连接请求。客户端会发送位码SYN(请求建立连接),以及序列号x(seq=x),TCP规定,SYN报文段(即SYN=1的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。

第二次握手:

服务端Server接受到请求报文段之后。如同意建立连接,则向客户端发送确认消息。在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。注意。这个报文段也不能携带数据,但同样要消耗掉一个序号。这时服务端进程进入SYN-RCVD(同步收到)状态。

第三次握手:

客户端Client收到服务端Server的确认后,还要向服务端给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。这时,TCP连接已经建立,客户端进入ESTABLISHED(已连接状态)。当服务端收到客户端的确认之后,也进入ESTABLISHED状态。

总结:

客户端在三次握手中,状态的转变是:CLOSED->SYN_SEND->ESTABLISHED

服务端在三次握手中,状态的转变是:CLOSED->LISTENED->SYN_RCVD->ESTABLISHED

问题一:为什么不可以两次握手,为什么客户端还要再发送一次确认?

答:消除旧有连接请求的SYN消息对新连接的干扰,同步连接双方的序列号和确认号并交换TCP 窗口大小信息。

比如说这种异常情况:客户端发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达服务端。本来这是一个早已失效的报文段。但服务端收到此失效的连接请求报文段后,就误以为是客户端又发出一次新的连接请求。于是就向客户端发出确认报文段,同意建立连接。假定不采用三次握手,那么只要服务端发出确认,新的连接就建立了。

问题二:什么是SYN攻击?如何检测它?

在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.

Syn攻击就是 攻击客户端 在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直 至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

Syn攻击是一个典型的DDOS攻击。检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击:

netstat -n -p TCP | grep SYN_RECV

一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等.

但是不能完全防范syn攻击。

四次挥手过程说明:

在客户端和服务端已经建立连接的情况下,需要四次挥手来断开连接。如下图所示:

第一次挥手:

客户端发送一个FIN=1的报文段和顺序号为u(seq=u)的请求关闭消息(客户端没有消息要发给你了,我准备关闭连接了,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK)。客户端进入FIN-WAIT-1状态,等待服务端的FIN报文段。

第二次挥手:

服务端收到客户端的FIN报文段,会发送一个确认报文段ACK=1,以及确认序列号ack=u+1,还有自己的序列号seq=v(告诉客户端,我已经收到你的请求关闭消息,但是我还没准备好,请继续等待),服务单进入CLOSE-WAIT阶段,此时服务端还未关闭。

第三次挥手:

服务端向客户端发送FIN=1报文段(告诉Client端,好了,我这边数据发完了,准备好关闭连接了),ACK=1,序列号seq=w,ack=u+1,服务端进入LAST-ACK状态

第四次挥手:

客户端收到服务端发来的FIN=1报文段,给服务端发送ACK=1报文段,序列号seq=u+1,ack=w+1的消息。这时客户端就可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传 ,客户端等待了2MSL后依然没有收到回复,客户端关闭。服务端也关闭。

总结:

客户端在四次挥手中的状态变化是:ESTABLISHED -> FIN-WAITED-1 -> FIN-WAITED-2 -> TIME-WAITED -> CLOSED

服务单在四次挥手中的状态变化是:ESTABLISHED -> CLOSE-WAITED LAST-ACK -> CLOSED

 

问题一:为什么在第四次回收后会有2个MSL的延时?

首先了解MSL,Maximum Segment Lifetime,最大报文生存时间,2个MSL是报文段发送和接受的最长时间。

假定网络不可靠,那么第四次发送的ACK可能丢失,即服务端无法收到这个ACK,如果服务端收不到这个确认ACK,服务端会定时向客户端端重复发送FIN,直到服务单端收到客户端的确认ACK。所以这个2MSL就是用来处理这个可能丢失的ACK的。

问题二:为什么握手只要三次,挥手却需要四次?

在TCP连接中,服务端SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中,服务端向客户端发送的ACK和FIN是分两次发送的。因为在服务端接受到客户端的FIN后,服务端还有数据要传输的话,所以先发送ACK,等服务端处理完自己的事情后就可以发送FIN断开连接了。

下篇预告:

TCP长连接与短连接,与Socket的联系

参考链接:

漫谈TCP

TCP的三次握手和四次挥手

TCP协议三次握手过程分析

计算机网络——TCP三次、四次握手详解

你应该这么理解TCP的三次握手和四次挥手的更多相关文章

  1. 【俗话说】换个角度理解TCP的三次握手和四次挥手

    PS:通俗一点的解释都会在引用块中 Nothing is true, Everything is permitted. 0. 什么是TCP TCP,全称Transmission Control Pro ...

  2. 理解 TCP/IP 三次握手与四次挥手

    TCP建立连接为什么是三次握手,而不是两次或四次? TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6. 顺便说一句,原则上任何数据传输都无法确保绝对可靠,三次握手只是确保可靠的基本需要 ...

  3. 理解TCP/IP三次握手与四次挥手的正确姿势

    背景 注:以下情节纯属虚构,我并没有女朋友==. 和女朋友异地恋一年多,为了保持感情我提议每天晚上视频聊天一次. 从好上开始,到现在,一年多也算坚持下来了. 问题 有时候聊天的过程中,我的网络或者她的 ...

  4. TCP/IP三次握手与四次挥手的正确姿势

    0.史上最容易理解的:TCP三次握手,四次挥手 https://cloud.tencent.com/developer/news/257281 A 理解TCP/IP三次握手与四次挥手的正确姿势http ...

  5. TCP的三次握手与四次挥手理解及面试题

    TCP的三次握手与四次挥手理解及面试题(很全面) 转载自:https://blog.csdn.net/qq_38950316/article/details/81087809 本文经过借鉴书籍资料.他 ...

  6. TCP的三次握手与四次挥手详解

    TCP的三次握手与四次挥手是TCP创建连接和关闭连接的核心流程,我们就从一个TCP结构图开始探究中的奥秘  序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序 ...

  7. 【图解】给面试官解释TCP的三次握手与四次挥手-Web运用原理及网络基础

    作者 | Jeskson 来源 | 达达前端小酒馆 轻松了解HTTP协议 为什么要学习网络协议呢?为什么要学习计算机完了呢?显然这很重要,至少能够帮助你找到工作的原因之一,学习网络知识点太多太多,没有 ...

  8. TCP 的三次握手和四次挥手

    参考资料: 1.TCP的三次握手与四次挥手理解及面试题: 2.Http协议三次握手和四次挥手: 3.TCP通信的三次握手和四次撒手的详细流程(顿悟) 前置: 序号(也称序列号) - Sequence ...

  9. TCP的三次握手与四次挥手

    TCP的三次握手与四次挥手 一.TCP(Transmission Control Protocol 传输控制协议) TCP是面向对连接,可靠的进程到进程通信的协议 TCP是提供全双工服务,即数据可在同 ...

随机推荐

  1. leetcode234

    /** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNo ...

  2. 【391】栈与队列,Python实现

    参考:python实现stack(栈)和队列(queue) - hjhmpl123的博客 - CSDN博客 参考:Python3 数据结构 | 菜鸟教程 栈和队列是两种基本的数据结构,同为容器类型.两 ...

  3. 550 5.7.1 Client does not have permissions to send as this sender

    收发邮件时出现以上这种情况,系统提示550 5.7.1 Client does not have permissions to send as this sender,这是什么原因赞成的呢? 活动目录 ...

  4. 28.Hibernate-HQL查询.md

    目录 1.概述 2.HQL实例 3.Criteria 查询 4.SQL本地查询 5.分页 1.概述 1)Get/load主键查询 2)对象导航查询 3)HQL查询, Hibernate Query l ...

  5. springmvc controller方法返回值

  6. Ubuntu安装软件提示boot空间不足

    用sudo apt-get install gitlab-ci-multi-runner安装应用都会出现“gzip: stdout: No space left on device”的问题. boot ...

  7. HDU 5734 Acperience(数学推导)

    Problem Description Deep neural networks (DNN) have shown significant improvements in several applic ...

  8. SQL Server XML 查询

    [参考1] 18个小实例入门SQLServer XML查询 [参考2] 转载---SQL Server XML基础学习之<5>--XQuery(query)

  9. VS2015 提示 无法启动 IIS Express Web 服务器

    好久没有写东西了,不是没的写,是没时间了,今天快下班了,正好遇到这个一个问题,我就记录下来,以防忘记. 我定义了一个项目,Demo代码也写好了,然后,我们就把写好的项目代码加入到了源代码管理工具里.然 ...

  10. ScrollView嵌套Linearlayout显示不全的解决办法

    以为ScrollView只能嵌套一个元素,所以把几个控件都包裹在了一个LinearLayout中了.但是发现底部显示不全,滑动不到最底下. 代码: <ScrollView android:id= ...