TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接,就好像你给别人打电话。必须等线路接通了、对方拿起话筒建立了连接才干相互通话。

  一个TCP连接必须要经过三次“对话”才干建立起来。当中的过程非常复杂,我们这里仅仅做简单、形象的介绍,你仅仅要做到能够理解这个过程就可以。

我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,能够吗?”,这是第一次对话。主机B向主机A发送允许连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“能够,你什么时候发?”。这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我如今就发,你接着吧!

”。这是第三次对话。

三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后。主机A才向主机B正式发送数据。

   

1. 建立连接三次握手

  TCP用三次握手(three-way handshake)过程创建一个连接。

在连接创建过程中,非常多參数要被初始化,比如序号被初始化以保证按序传输和连接的强壮性。

  一对终端同一时候初始化一个它们之间的连接是可能的。但一般是由一端打开一个套接字(socket)然后监听来自还有一方的连接。这就是通常所指的被动打开(passive open)。

server端被被动打开以后,用户端就能開始创建主动打开(active open)。

  1)client通过向server端发送一个SYN来创建一个主动打开,作为三路握手的一部分。

client把这段连接的序号设定为随机数 A。

  2)server端应当为一个合法的SYN回送一个SYN/ACK。

ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。

  3)最后。client再发送一个ACK。当服务端受到这个ACK的时候,就完毕了三路握手。并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1。而响应则为 B+1。

   

  Win:窗体字段明白指出如今允许对方发送的数据量(常常变化)

  Len:TCP数据段长度

  MSS(Maximum Segment Size):最大报文段长度,即每一个TCP报文段中的数据字段的最大长度.这里须要在握手的时候进行协商,两方都给出MSS。最后以最小MSS确定为终于的MSS。IP数据报最大传输单位为MTU(Maximum Transmission Unit,Effect of short board),对于大多数使用以太网的局域网来说,MTU=1500。

MSS往往基于MTU计算出来,通常MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460,假设serverMSS=1460,而client的MSS=1440,终于为1440。

  在TCP的三次握手中。不仅是建立了连接,还让两方交换了有效信息。步骤例如以下:

  1) 嗨~ , 这是我sequence number和MSS

  2) 我收到啦~, 这是我sequence number和MSS

  3) 我也收到~

为什么须要三次握手?

  简单地说,就是要保证在一段有效时间内,两方收到对方的有效信息。

  一个简单样例,A发给B,B回复A,假设A不再回复B。B怎样知道A收到了自己的信息?

  谢希仁版《计算机网络》中的样例是这种。“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后。就误觉得是client再次发出的一个新的连接请求。于是就向client发出确认报文段,允许建立连接。假设不採用“三次握手”。那么仅仅要server发出确认,新的连接就建立了。因为如今client并没有发出建立连接的请求。因此不会理睬server的确认。也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。

这样。server的非常多资源就白白浪费掉了。

採用“三次握手”的办法能够防止上述现象发生。

比如刚才那种情况,client不会向server的确认发出确认。server因为收不到确认,就知道client并没有要求建立连接。

”。

  无论哪个样例,都是为了满足”在不可靠信道上可靠地传输信息”这一需求。请注意这里的本质需求,信道不可靠,传输数据要可靠。还是那句话,就是要保证在一段有效时间内,两方收到对方的有效信息。

SYN攻击

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

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

  SYN攻击是一个典型的DDOS攻击。

检測SYN攻击非常的方便,当你在server上看到大量的半连接状态时,特别是源IP地址是随机的。基本上能够断定这是一次SYN攻击.在Linux下能够例如以下命令检測是否被Syn攻击:

netstat -n -p TCP | grep SYN_RECV

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

  可是不能全然防范SYN攻击。

Socket状态相应

  Socket API 和 TCP 协议中各个状态是怎样相应的呢?我们能够通过下图来看:

  

2. 断开连接四次挥手

  因为TCP连接是全双工的,因此每一个方向都必须单独进行关闭。这个原则是当一方完毕它的数据发送任务后就能发送一个FIN来终止这个方向的连接。

比方server收到一个FIN仅仅意味着client不再发送数据。但它还能够向client发送数据。当server不再发数据了,他也要向client发送FIN。首先进行关闭的一方将运行主动关闭,而还有一方运行被动关闭。

  

    

四次挥手步骤例如以下:

  1)clientA发送一个FIN,用来关闭客户A到serverB的数据传送。

  2)serverB收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。

  3)serverB关闭与clientA的连接,发送一个FIN给clientA。

  4)clientA发回ACK报文确认,并将确认序号设置为收到序号加1。

状态变化

  

  FIN_WAIT_1: 当SOCKET在ESTABLISHED状态。主动关闭连接时,向对方发送FIN报文,此时该SOCKET进入到FIN_WAIT_1状态。当对方回应ACK报文后。则进入到FIN_WAIT_2状态。(主动方)

  FIN_WAIT_2:处于FIN_WAIT_2状态下的SOCKET为半连接状态,等待对方发起断开要求,(注意对方能够在断开时捎带信息)稍后再关闭连接。

(主动方)

  TIME_WAIT: 收到了对方FIN报文,并发送出了ACK报文。等待2MSL后就可以回到CLOSED状态了。

  注意:在FIN_WAIT_1状态下,假设收到了对方同一时候带FIN和ACK标志的报文(复用一个报文)时,能够直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)

  CLOSING(比較少见): 假设两方差点儿同一时候试图断开一个SOCKET的话,那么就出现了两方同一时候发送FIN报文的情况,即会出现CLOSING状态,表示两方都试图关闭SOCKET连接。

  CLOSE_WAIT: 等待关闭连接。当对方发送FIN报文。回应ACK报文给对方后,则进入到CLOSE_WAIT状态。假设此时没有数据发送给对方。就能够关闭这个SOCKET,发送FIN报文给对方。即关闭连接。

(被动方)

  LAST_ACK: 被动关闭方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后。进入到CLOSED状态。(被动方)

  CLOSED: 连接中断。

Socket状态变化

  

    

參考:

https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

http://www.kuqin.com/shuoit/20141018/342719.html

http://hackerxu.com/2014/11/16/TCP.html

https://www.centos.bz/2012/08/tcp-establish-close/

http://blog.csdn.net/xifeijian/article/details/12777187

http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html

http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520118139252103/

https://commons.wikimedia.org/wiki/File:Tcp_close.svg

$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('

    ').addClass('pre-numbering').hide();
    $(this).addClass('has-numbering').parent().append($numbering);
    for (i = 1; i ').text(i));
    };
    $numbering.fadeIn(1700);
    });
    });

TCP具体解释(2):三次握手与四次挥手的更多相关文章

  1. TCP协议中的三次握手和四次挥手(图解)【转】

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...

  2. TCP的基本概念三次握手,四次挥手

    TCP的特性 TCP提供一种面向连接的.可靠的字节流服务 在一个TCP连接中,仅有两方进行彼此通信.广播和多播不能用于TCP TCP使用校验和,确认和重传机制来保证可靠传输 TCP使用累积确认 TCP ...

  3. TCP常见的定时器三次握手与四次挥手

    1.TCP常见的定时器 在TCP协议中有的时候需要定期或者按照某个算法对某个事件进行触发,那么这个时候,TCP协议是使用定时器进行实现的.在TCP中,会有七种定时器: 建立连接定时器(connecti ...

  4. 真的懂了:TCP协议中的三次握手和四次挥手(关闭连接时, 当收到对方的FIN报文时, 仅仅表示对方不在发送数据了, 但是还能接收数据, 己方也未必全部数据都发送对方了。相当于一开始还没接上话不要紧,后来接上话以后得让人把话讲完)

    一.TCP报文格式 下面是TCP报文格式图: (1) 序号, Seq(Sequence number), 占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2) 确 ...

  5. python网络编程-TCP协议中的三次握手和四次挥手(图解)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  6. TCP协议中的三次握手和四次挥手(图解)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  7. [转]TCP协议中的三次握手和四次挥手(图解)

    本文转自:http://blog.csdn.net/whuslei/article/details/6667471 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来 ...

  8. 【转】 TCP协议中的三次握手和四次挥手(图解)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  9. TCP协议中的三次握手和四次挥手(图解)(转载http://blog.csdn.net/whuslei/article/details/6667471)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源 ...

  10. TCP协议中的三次握手和四次挥手

    转自: http://blog.csdn.net/whuslei/article/details/6667471/ 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示:

随机推荐

  1. selenium python (八)定位frame中的对象

    #!/usr/bin/python# -*- coding: utf-8 -*-__author__ = 'zuoanvip'#在测试过程中经常遇到frame嵌套的应用,加入页面上有A.B两个fram ...

  2. eclipse 报错汇总

    1.Eclipse 启动时,报错: Fail to create the java virtual machine   已解决.方法:eclipse.ini 中-vmargs-Dosgi.requir ...

  3. SQL求 交集 并集 差集

    故事是这样的….. 故事情节: 表 tb_test 有两列, colA , colB; 求 colA , colB 的并交差集… -- 计算并集 SELECT DISTINCT colB FROM t ...

  4. C语言实现strcpy

    strcpy.h: #ifndef STRCPY_H #define STRCPY_H #include <stdio.h> char *cat_strcpy(char *dst, con ...

  5. MFC学习20160718(GetModuleFileName&amp;&amp;GetAppDataPath)

    1.标题栏设置 一.对话框标题栏内容为静态 直接在对话框属性“General”的“Caption”中修改. 二.对话框标题栏内容为动态生成的 在对应对话框的初始化函数OnInitDialog()中添加 ...

  6. iOS优秀博客收录(持续更新)

    唐巧 王巍 破船之家 NSHipster Limboy 无网不剩 念茜的博客 Xcode Dev Ted’s Homepage txx’s blog KEVIN BLOG 阿毛的蛋疼地 亚庆的 Blo ...

  7. WinForm 中两个窗口之间传递数据

    方法有很多种,这里介绍项目中使用的两种 一.通过委托+事件的方法进行传值 (点击Form2中的button1按钮,将会把Form2中的textbox.text 传给Form1中的 lable.text ...

  8. Python 最佳实践

    前言 对我来说,以前每次面试是我审视自己,检验自己的一种方式.每次准备面试,以及被面试官问住的时候才会发现,其实我python我学的还不够好.工作中也是,可以从其他的同事那里获得成长.但是我今天说的是 ...

  9. Struts Convention Plugin 流程 (2.1.6+)

    首先添加lib: <dependency> <groupId>org.apache.struts</groupId> <artifactId>strut ...

  10. Python的数据处理学习(二)

    本文参考Paul Barry所著的<Head First Python>一书,参考代码均可由http://python.itcarlow.ie/站点下载.本文若有任何谬误希望不吝赐教~ 二 ...