TCP具体解释(2):三次握手与四次挥手
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 = $('
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i ').text(i));
};
$numbering.fadeIn(1700);
});
});
TCP具体解释(2):三次握手与四次挥手的更多相关文章
- TCP协议中的三次握手和四次挥手(图解)【转】
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...
- TCP的基本概念三次握手,四次挥手
TCP的特性 TCP提供一种面向连接的.可靠的字节流服务 在一个TCP连接中,仅有两方进行彼此通信.广播和多播不能用于TCP TCP使用校验和,确认和重传机制来保证可靠传输 TCP使用累积确认 TCP ...
- TCP常见的定时器三次握手与四次挥手
1.TCP常见的定时器 在TCP协议中有的时候需要定期或者按照某个算法对某个事件进行触发,那么这个时候,TCP协议是使用定时器进行实现的.在TCP中,会有七种定时器: 建立连接定时器(connecti ...
- 真的懂了:TCP协议中的三次握手和四次挥手(关闭连接时, 当收到对方的FIN报文时, 仅仅表示对方不在发送数据了, 但是还能接收数据, 己方也未必全部数据都发送对方了。相当于一开始还没接上话不要紧,后来接上话以后得让人把话讲完)
一.TCP报文格式 下面是TCP报文格式图: (1) 序号, Seq(Sequence number), 占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2) 确 ...
- python网络编程-TCP协议中的三次握手和四次挥手(图解)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- TCP协议中的三次握手和四次挥手(图解)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- [转]TCP协议中的三次握手和四次挥手(图解)
本文转自:http://blog.csdn.net/whuslei/article/details/6667471 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来 ...
- 【转】 TCP协议中的三次握手和四次挥手(图解)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- TCP协议中的三次握手和四次挥手(图解)(转载http://blog.csdn.net/whuslei/article/details/6667471)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源 ...
- TCP协议中的三次握手和四次挥手
转自: http://blog.csdn.net/whuslei/article/details/6667471/ 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示:
随机推荐
- selenium python (八)定位frame中的对象
#!/usr/bin/python# -*- coding: utf-8 -*-__author__ = 'zuoanvip'#在测试过程中经常遇到frame嵌套的应用,加入页面上有A.B两个fram ...
- eclipse 报错汇总
1.Eclipse 启动时,报错: Fail to create the java virtual machine 已解决.方法:eclipse.ini 中-vmargs-Dosgi.requir ...
- SQL求 交集 并集 差集
故事是这样的….. 故事情节: 表 tb_test 有两列, colA , colB; 求 colA , colB 的并交差集… -- 计算并集 SELECT DISTINCT colB FROM t ...
- C语言实现strcpy
strcpy.h: #ifndef STRCPY_H #define STRCPY_H #include <stdio.h> char *cat_strcpy(char *dst, con ...
- MFC学习20160718(GetModuleFileName&&GetAppDataPath)
1.标题栏设置 一.对话框标题栏内容为静态 直接在对话框属性“General”的“Caption”中修改. 二.对话框标题栏内容为动态生成的 在对应对话框的初始化函数OnInitDialog()中添加 ...
- iOS优秀博客收录(持续更新)
唐巧 王巍 破船之家 NSHipster Limboy 无网不剩 念茜的博客 Xcode Dev Ted’s Homepage txx’s blog KEVIN BLOG 阿毛的蛋疼地 亚庆的 Blo ...
- WinForm 中两个窗口之间传递数据
方法有很多种,这里介绍项目中使用的两种 一.通过委托+事件的方法进行传值 (点击Form2中的button1按钮,将会把Form2中的textbox.text 传给Form1中的 lable.text ...
- Python 最佳实践
前言 对我来说,以前每次面试是我审视自己,检验自己的一种方式.每次准备面试,以及被面试官问住的时候才会发现,其实我python我学的还不够好.工作中也是,可以从其他的同事那里获得成长.但是我今天说的是 ...
- Struts Convention Plugin 流程 (2.1.6+)
首先添加lib: <dependency> <groupId>org.apache.struts</groupId> <artifactId>strut ...
- Python的数据处理学习(二)
本文参考Paul Barry所著的<Head First Python>一书,参考代码均可由http://python.itcarlow.ie/站点下载.本文若有任何谬误希望不吝赐教~ 二 ...