上次已经说过,没有协议,不成方圆,计算机之间的通信更是依赖于协议。今天就重点分析一下 TCP 协议。

传输控制协议 TCP 是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络 OSI 模型中,它完成第四层传输层所指定的功能,用户数据包协议(UDP)是同一层内另一个重要的传输协议。

先来复习一下 OSI 的七层模型。

TCP 工作在 OSI 中的第四层——Transport 层,IP 在第三层——Network 层,ARP 在第二层——Data Link 层;在第二层上的数据,我们把它叫 Frame,在第三层上的数据叫 Packet,第四层的数据叫 Segment。 同时,我们需要知道,数据从应用层发下来,会在每一层都会加上头部信息,进行封装,然后再发送到数据接收端。

TCP 协议所涉及到的知识太多,没有办法兼顾,我主要想谈谈 3 次握手和 4 次挥手。TCP 的运行可以分为三个阶段,建立连接、传送数据、关闭连接。3 次握手 4 次挥手就对应着建立连接和关闭连接。

操作系统将 TCP 连接抽象为套接字表示的本地端点,作为编程接口给程序使用。在 TCP 连接的生命期内,本地端点要经历一系列的状态改变。我们经常会听到面向 Socket 编程,这是后话了。

要想知道握手是怎样进行了,我们先来看看 TCP 的报文结构。

有以下几点需要说明

TCP 报文中没有 IP 地址,有源端口和目的端口,IP 地址在网络层中的 Packet 中。

Sequence Number(序号),用来标识从 TCP 发送端向 TCP 接收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;通信双方要知道对方的初始化序号,这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序(TCP 会用这个序号来拼接数据)。

Acknowledgment Number(确认号)32 位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加 1。不过,只有当标志位中的 ACK 标志(下面介绍)为 1 时该确认序列号的字段才有效。主要用来解决不丢包的问题。

SYN,表示同步序号,用来建立连接。SYN 标志位和 ACK 标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1。

这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有 SYN 的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行 TCP 三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行 TCP 的三次握手。

ACK,TCP 协议规定,只有 ACK=1 时有效,也规定连接建立后所有发送的报文的 ACK 必须为 1 。

FIN,表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送 FIN 标志位的 TCP 数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。

三次握手的过程,即建立一个 TCP 连接的过程,在 Socket 编程中,这一过程由客户端执行 connect 来触发,整个流程如上图所示。

第一次握手:Client 将标志位 SYN 置为1,随机产生一个值 seq=x,并将该数据包发送给 Server,Client 进入 SYN_SENT 状态,等待 Server 确认。

第二次握手:Server 收到数据包后由标志位 SYN=1 知道 Client 请求建立连接,Server 将标志位 SYN 和 ACK 都置为1,ack=x+1,随机产生一个值 seq=y,并将该数据包发送给 Client 以确认连接请求,Server 进入 SYN_RCVD 状态。

第三次握手:Client 收到确认后,检查 ack 是否为 x+1,ACK 是否为1,如果正确则将标志位 ACK 置为1,ack=y+1,并将该数据包发送给 Server,Server 检查 ack 是否为 y+1,ACK 是否为1,如果正确则连接建立成功,Client 和 Server 进入 ESTABLISHED 状态,完成三次握手,随后 Client 与 Server 之间可以开始传输数据了。

注意,不要搞混了 SYN、ACK 只是标志位,seq 是序号,防止乱序,ack 是确认号,主要用来解决不丢包的问题。

四次挥手,即终止 TCP 连接,就是指断开一个 TCP 连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在 Socket 编程中,这一过程由客户端或服务端任一方执行 close 来触发。

由于 TCP 连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个 FIN 来终止这一方向的连接,收到一个 FIN 只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个 TCP 连接上仍然能够发送数据,直到对方也发送了 FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

第一次挥手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number 和 Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;

第二次挥手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;

第三次挥手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;

第四次挥手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明 Server 端已正常关闭,那好,主机1也可以关闭连接了。

为什么建立连接需要 3 次握手 ?

因为,TCP 协议要保证两端数据的可靠传输,最少就要采取 3 次交互。三次是保证双方互相明确对方能收能发的最低值。下面有个生活中的例子可以感受一下。

TCP之所以使用三次握手,完全是一种为了解决“两军问题”所采用的折衷的设计。所谓“两军问题”,就是红军想告诉蓝军明天下午一起对敌开火,那么红军会派信使 1 号跑过去告诉蓝军,蓝军收到消息再派信使 2 号告诉红军收到,注意,这时蓝军并不知道红军是否收到蓝军的回复。因此需要红军收到回复再派信使 3 号告诉蓝军收到回复,而此时红军也不知道蓝军是否收到回复,因此蓝军收到信使 3 号的消息再派信使 4 号…

还有一个秒懂例子,看到这个真的笑死我了。但是这个例子不严谨哦,权当一乐就好。

三次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天balabala……”

两次握手:
“喂,你听得到吗?”
“我听得到呀”
“喂喂,你听得到吗?”
“草,我听得到呀!!!!”
“你TM能不能听到我讲话啊!!喂!”
“……”

四次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,你能听到我吗?”
“……不想跟傻逼说话”

所以说,握手次数要保持刚刚好,2 次不够,4 次多了。

SYN 攻击

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

检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。

如何防御 SYN 攻击 ?

SYN 攻击不能完全被阻止,除非将 TCP 协议重新设计。我们所做的是尽可能的减轻 SYN 攻击的危害,常见的防御 SYN 攻击的方法有如下几种:

缩短超时(SYN Timeout)时间

增加最大半连接数

过滤网关防护

SYN cookies 技术

TCP 建立连接为什么要握 3 次手?的更多相关文章

  1. 通俗易懂地讲解TCP建立连接的三次握手和释放连接的四次挥手

    TCP建立连接时,为什么要进行三次挥手? 每一次TCP连接都需要三个阶段:连接建立.数据传送和连接释放.三次握手就发生在连接建立阶段. 在谢希仁著<计算机网络>第四版中讲三次握手的目的是为 ...

  2. TCP建立连接的三次握手过程

    TCP是因特网中的传输层协议,使用三次握手协议建立连接,下面是TCP建立连接的全过程. 上图画出了TCP建立连接的过程.假定主机A运行的是TCP客户程序,B运行的是TCP服务器程序.最初两端的TCP进 ...

  3. TCP 建立连接:三次握手

    转自:http://www.cnblogs.com/winner-0715/p/5032661.html 感谢! TCP 建立连接过程 TCP是因特网中的传输层协议,使用三次握手协议建立连接,下面是T ...

  4. TCP建立连接三次握手和释放连接四次握手

    TCP建立连接三次握手和释放连接四次握手     [转载]http://blog.csdn.net/guyuealian/article/details/52535294   在谈及TCP建立连接和释 ...

  5. TCP建立连接为什么是三次握手,为什么不是两次或四次?

    什么是三次握手 学过网络编程的人,应该都知道TCP建立连接的三次握手,下面简单描述一下这个过程. 如图所示 第一次握手:客户端发送TCP包,置SYN标志位为1,将初始序号X,保存在包头的序列号(Seq ...

  6. 【转】TCP建立连接三次握手和释放连接四次握手

    在谈及TCP建立连接和释放连接过程,先来简单认识一下TCP报文段首部格式的的几个名词(这里只是简单说明,具体请查看相关教程) 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数 ...

  7. TCP建立连接的三次握手和TCP连接断开的四次挥手

    1. TCP建立连接的3次握手 2. TCP断开连接的四次挥手 [注意]中断连接端可以是Client端,也可以是Server端. 图3—Client端主动发起关闭连接请求 1. 假设Client端主动 ...

  8. TCP建立连接和释放连接过程

    TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.TCP建立连接需要三次握手,释放连接需要四次握手. 1.TCP整 ...

  9. 详解TCP建立连接全过程

    TCP是因特网中的传输层协议,使用三次握手协议建立连接,下面是TCP建立连接的全过程. 上图画出了TCP建立连接的过程.假定主机A是TCP客户端,B是服务端.最初两端的TCP进程都处于CLOSED状态 ...

随机推荐

  1. 小程序web-view wx.miniProgram.postMessage 坑记录

    web-view吧,其实微信官方应该是非常不支持在小程序上嵌套web的,它希望你直接用小程序上的代码,而放弃web的实现,当然,也是为了防止用小程序去嵌套别的广告页面.所以官方对web-view的操作 ...

  2. java所搜引擎slor学习笔记(一)

    java搜索引擎有很多,比较熟悉的就是slor和lucene. luncene: 概念:全文检索是计算机程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置.当用户查 ...

  3. 【codeforces】【比赛题解】#940 CF Round #466 (Div. 2)

    人生的大起大落莫过如此,下一场我一定要回紫. [A]Points on the line 题意: 一个直线上有\(n\)个点,要求去掉最少的点,使得最远两点距离不超过\(d\). 题解: 暴力两重fo ...

  4. flask插件系列之flask_uploads上传文件

    前言 flask可以实现上传文件和下载文件的基本功能,但如果想要健壮的功能,使用flask_uploads插件是十分方便的. 安装 pip install flask_uploads 基本使用 # e ...

  5. linux sigaction 函数 用法释义

    使用 sigaction 函数: signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX 标准定义的信号处 ...

  6. jquery记忆笔记

    1.javascript需要注意的一些问题: ①不要使用==比较,始终坚持使用===比较. false == 0; // true false === 0; // false ②NaN这个特殊的Num ...

  7. python高性能web框架——Japronto

    近期做了一个简单的demo需求,搭建一个http server,支持简单的qa查询.库中有10000个qa对,需要支持每秒10000次以上的查询请求. 需求比较简单,主要难点就是10000+的RPS. ...

  8. python并行计算(持续更新)

    工作中需要对tensorflow 的一个predict结果加速,利用python中的线程池 def getPPLs(tester,datas): for line in datas: tester(l ...

  9. git —— 异常1,index.lock

    git提交过程中出现的问题 解决方法:找到 index.lock文件将其删除 一般 index.lock 在.git下面, 有时 .git 是隐藏的,但是无论怎样, 可以通过 everything 找 ...

  10. Spring框架的基本使用(AOP部分)

    AOP,Aspect Oriented Programming,意为面向切面编程,是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP采取横向抽取机制,取代了传统纵向继承体系重复 ...