本文基于个人所学和网上博文所整理,若有不妥处,欢迎留言指出

TCP连接过程中标志位的意义:

字符缩写 描述
SYN 同步序号,表示此报文是一个连接请求或连接接受报文
ACK 确认位,对接收到的报文的确认
FIN 终止位,表示发送方完成数据发送,用来释放一个连接
RST 复位连接,表示TCP连接中出现严重错误
PSH 推送位,尽可能快递将数据送往接受进程

一、三次握手建立

1、三次握手建立连接详解

TCP建立连接要进行“三次握手”,即交换三个分组。大致流程如下:

(1)客户端向服务器发送一个SYN J,并进入SYN_SEND状态,等待服务器确认;;

(2)服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1,此时服务器 进入SYN_RECV状态;

(3)客户端再想服务器发一个确认ACK K+1,客户端和服务器进入 ESTABLISHED状态,完成三次握手。。

三次握手发生在socket的那几个函数:

从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。

总结:客户的的connect在第三次握手的第二次返回,二服务器的accept在三次握手的第三次返回。

2、若是出现丢包的情况,会如何?(来自:TCP 为什么是三次握手,为什么不是两次或四次?车小胖的回答)(A对应客户端,B对应服务器)

(1)第一个包,即A发给B的SYN 中途被丢,没有到达B

A会周期性超时重传,直到收到B的确认;

(2)第二个包,即B发给A的SYN +ACK 中途被丢,没有到达A

B会周期性超时重传,直到收到A的确认;

(3)第三个包,即A发给B的ACK中途丢失,没有到达B

A发完ACK,单方面认为TCP为Established状态,而B显然认为TCP为Active状态:

  • 假定此时双方都没有数据发送,B会周期性超时重传,直到收到A的确认,收到之后B的TCP 连接也为 Established状态,双向可以发包。
  • 假定此时A有数据发送,B收到A的 Data + ACK,自然会切换为established 状态,并接受A的 Data。
  • 假定B有数据发送,数据发送不了,会一直周期性超时重传SYN + ACK,直到收到A的确认才可以发送数据。

3、TCP 为什么是三次握手,为什么不是两次或四次?

三次握手的目的是什么?以下引用知乎作者郭无心的回答:

在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”

另外,三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。我们可以通过打招呼的例子来说明。

二、四次挥手释放

1、四次挥手释放过程详解

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。 
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。 
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。 
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。 
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

这里引用whuslei的博文TCP协议中的三次握手和四次挥手(图解)中更为生动的解释:

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

2、为什么连接的时候是三次握手,关闭的时候却是四次挥手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

3、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:主要是防止最后一个ACK丢失!!!虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。另外在等待2MLS的时间中,五元组(源、目IP和端口号以及协议号)都不能用,是为了防止网络中迟来数据。

Ref:

http://www.cnblogs.com/huhuuu/p/3572485.html

http://blog.csdn.net/whuslei/article/details/6667471

http://www.cr173.com/exam/Cisco_17954_1.html

http://www.8btc.com/baizhantingjiangjun(将军问题)

TCP中三次握手建立和四次握手释放以及相关问题的更多相关文章

  1. TCP中三次挥手四次握手

    1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...

  2. socket中TCP的三次握手连接和四次握手释放

    三次握手连接 A: 我进来了啊 B:(有人来了安排个位子)回复:好的你进来吧 A:好的: 客户端向服务器发送一个SYN J 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1 客户 ...

  3. TCP\IP三次握手连接,四次握手断开分析

    TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...

  4. TCP三次握手连接与四次握手断开

    http://blog.csdn.net/whuslei/article/details/6667471(三次握手与四次握手) 1. TCP的三次握手最主要是防止已过期的连接再次传到被连接的主机. 如 ...

  5. 为什么TCP连接需要三次握手分开需要四次握手?

    TCP的三次握手和四次断开TCP是一个面向连接的服务,面向连接的服务是电话系统服务模式的抽象,每一次完整的数据传输都必须经过建立连接,数据传输和终止连接3个过程,TCP建立连接的过程称为三次握手,下面 ...

  6. TCP/IP 三次握手和四次握手

    三次握手建立连接: 第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己 ...

  7. TCP/IP三次握手四次挥手

    本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图所示,给出了TCP通信过程的示意图. TCP 三次握手四次挥手 主要包括三部 ...

  8. TCP/IP协议三次握手与四次握手流程解析(转)

    一.TCP报文格式   下面是TCP报文格式图:       上图中有几个字段需要重点介绍下:  (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标 ...

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

    TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...

随机推荐

  1. 拼接index

    import MySQLdb import sys db = MySQLdb.connect(host="127.0.0.1", # your host, usually loca ...

  2. C# 简单工厂

    如下: public static IList<T> Create<T>(Type type) { if (type == typeof(List<T>)) { r ...

  3. Leetcode-跳跃游戏

    跳跃游戏     给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] ...

  4. 【转】网游服务器中的GUID(唯一标识码)实现-基于snowflake算法

    本文中的算法采用twitter的snowflake算法,具体请搜索介绍,原来是用Scala写的,因我项目需要,改写成C++语言,主要用于高效的生成唯一的ID, 核心算法就是毫秒级时间(41位)+机器I ...

  5. Java面试知多少

    1.谈谈&和&&的区别  1.&&是短路判断,在与其他语句一起判断时,第一个条件为假就不判断剩下的条件:   & 需要判断所有的条件  2.&是 ...

  6. Struts2中Action各种转发类型

    Struts2:Action中result的各种转发类型: 内部请求转发dispatcher(默认值) redirect.redirectAction.plainText1.redirect是重定向到 ...

  7. 普通Java类获取Spring的Bean的方法

    普通Java类获取Spring的Bean的方法 在SSH集成的前提下.某些情况我们需要在Action以外的类中来获得Spring所管理的Service对象. 之前我在网上找了好几好久都没有找到合适的方 ...

  8. mysql mariadb 密码设置

    原文:https://my.oschina.net/uyunsky/blog/109532 一.初始安装 Method 1:在/usr/local/mysql/bin/下:./mysqladmin - ...

  9. 计算器软件实现系列(六)windowform窗体+SQL+策略模式

    一 整体概述 这个计算器软件的功能和以前的功能基本上一样,只不过是数据的保存形式发生了变化,,以前用的是txt文件保存,现在更正用SQL数据库,现在更改了以前的文件保存形式,是三层架构中数据层的更换, ...

  10. python正则表达式函数match()和search()的区别详解

    match()和search()都是python中的正则匹配函数,那这两个函数有何区别呢? match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找 ...