浅探网络1---tcp协议详解(三次握手和四次挥手)
TCP协议是网络多层协议中运输层的最重要的协议之一,运输层是两台主机的进程之间的通信。除了TCP还有一个是UDP协议(用户数据包协议)
TCP全称是Transmission Control Protocol,意思是传输控制协议
一、TCP简介
1.TCP协议两个对等运输实体之间进行传送的数据单位是:TCP报文段
2.TCP提供的是面向连接的服务,在传送数据之前必须建立连接,数据传送完成之后需要关闭连接,TCP只可点对点,不可广播或多播,TCP连接是可靠的运输服务。
3.TCP的工作方式类似于打电话,打电话之前需要先拨号(号码就是连接的IP+端口号)连接,通话结束之后关闭连接
4.TCP提供可靠交付,即TCP传输的数据无差错、不丢失、不重复且有序
5.TCP支持全双工通信,即通信双方可随时发送数据,发送方发送完数据会先放到发送缓存中,发送方发送完毕就可以干别的事去了,TCP会在合适的时机将数据发送给接受方,接收方接收到数据会先把数据放到接收缓存中,应用程序会在合适的时机在缓存中获取数据。
6.TCP是面向字节流的,流入到进程或从进程中流出的是字节序列。而发送时和接收时除了传输的业务数据,可能还会额外加一些字节数据,用于发送方和接收方处理。比如在微信聊天中需要提醒接收方会添加@XXX,而接收方只需要接收有用信息,@信息是和业务无关的。
7.TCP连接的双方不是两个主机、不是两个IP地址、不是两个应用程序、而是两个套接字,每个套接字socket=(IP地址:端口号),每一个TCP连接必须有唯一的两个套接字,即TCP连接={套接字1,套接字2}={(IP1,port1),(IP2,port2)}
二、TCP三次握手和四次挥手
TCP是面向连接的协议,所以协议的基础就是需要有连接,而发起连接的一方可以称为客户端,等待连接的一方可以称为服务端。而TCP建立连接的过程称为握手,每次握手客户端和服务器之前需要交换三个报文段,因此也叫做“三次握手”。
在RFC973(TCP标准文档)中使用的名称是three way handshake,这里的handshake没有用复数,所以三次握手不太准确,应该叫三次报文握手,因为人与人之间握手的意思就是已经连接上了,手上摇晃了三次之后才最终握上,所以准确点说应该是握手成功了一次。但是三次握手的说法比较普遍,所以本文也叫做三次握手。在理解TCP连接之前,先来了解一些常量的含义
SYN:发起一个连接,同步位
FIN:关闭一个连接
ACK:确认连接有效
RST:重置连接
seq:序号,每次发送一次数据,seq=上一个seq+1
ack:应答序号
上图是TCP连接三次握手示意图
第一次握手:A向B发送连接请求报文,同步完syn=1,初始化序号seq=X,TCP协议规定syn=1的报文不允许携带数据,所以SYN=1即表示发起连接请求,当A发送第一次握手之后,A就进入了SYN-SENT状态,表示同步已发送
第二次握手:B接收到A发送的请求报文,如果同意连接,则向A发送确认。发送同步报文段SYN=1,seq=y,确认报文段ACK=1,确认序号ack=x+1。此时服务端进入SYN-RCVD状态,表示同步已接收
第三次握手:A接收到B的确认报文,再向B发起确认,设置ACK=1,确认序号seq=x+1,ack=y+1,此时TCP连接完成,双方都进入ESTAB-LISHED状态,表示连接以建立。
那么为什么需要三次,而不是两次就行,还需要最后再发送一次确认呢?或者说如果没有最后一次确认会发送什么?看看下面这种情况:
A发出连接请求,但是在网络中长时间滞留了而没有发送到B,此时由于A久久没有接收到B发送过来的确认请求,所以A就将连接释放了,在A释放了连接之后B又接收到了A发送过来迟到的连接请求,由于B不知道此时A已经释放了连接了,所以B认为是有效的连接,
此时B向A发送确认,同意建立连接(如果只要两次握手,那么此时B就已经进入了ESTAB-EISHED状态),此时A已经释放了连接,所以接收到B的确认请求也不会理睬,但是B还是认为连接有效而一直等待着A发送数据,就会导致B持有无效的连接而浪费资源。
而如果采用三次握手,那么B在发送完确认之后,只会进入到SYN-RCVD状态,并不会建立连接的等待数据的发送,除非A再次发送了确认请求。
TCP连接是双向的,所以TCP连接的释放是双方都可以发起的,以A为例发起释放连接,需要经过四次挥手,过程如下图示:
在连接释放之前,A和B都是出于ESTAB-LISHED状态,且可以数据传输,此时A开始进行关闭
第一次挥手:A向B发送关闭连接请求,FIN=1,seq=u(u的值等于数据传输的最后一个请求的序号+1),此时A进入FIN-WAIT-1状态,等待B确认。TCP规定FIN报文不可携带数据
第二次挥手:B接收到A的关闭连接请求,并发出关闭确认,ACK=1,seq=v(v的值等于B传送的最后一个字节的序号+1),ack=u+1,然后B进入CLOSE-WAIT(等待关闭)状态,且需要通知应用进程A需要关闭连接,不再发送数据过来了。
此时TCP连接进入半关闭状态,也就是A-B的连接已经关闭,B-A的连接还没有关闭,但A接收到B的关闭确认之后进入FIN-WAIT-2状态,等待B发送关闭连接报文
第三次挥手:若B没有数据再发送给A,则向A发送关闭连接报文,FIN=1,ACK=1,seq=w(w的值等于B传送的最后一个字节的序号+1),ack=u+1,并且B进入LAST-ACK(最后确认)状态,等待A的确认
第四次挥手:A收到B的关闭连接报文之后,再向B发送一次确认报文,ACK=1,seq=u+1,ack=w+1,并且进入到TIME-WAIT(时间等待)状态,需要等待2MSL时间之后才会进入到CLOSED状态,而B接收到关闭确认报文之后就直接进入CLOSED(关闭)状态。
这里有两个问题,一是为什么需要有四次握手,而不是两次或三次?二是A在发送关闭确认请求之后,为什么还需要等待2MSL长时间才进入CLOSED状态?(MSL一般是2分钟,2MSL就是4分钟)
回答一:和三次握手一样,挥手只用两次肯定是不够用的,那三次为什么也不够呢,因为第一次关闭连接是A向B发起的,表示A不会发送数据给B了,但是此时可能B还有数据需要传送给A,如果B在数据还没有传输完成就通知A,则数据就会丢失;如果B在数据传输完成之后再通知A,那么此时可能已经超时了,导致A以为发起的关闭连接失效了就会重新发送多次的关闭连接。而四次挥手比三次握手多的一次报文是B向A发送的关闭连接请求,表示B也已经不会发送数据给A了,这样就确保了双方都没有数据发送了,且都对对方的关闭连接做了关闭确认。
回答二:设置TIME-WAIT状态等待2MSL主要有两个原因:
原因1:防止第四次挥手丢失,如果A在发送第四次挥手报文之后马上进入CLOSED状态,而B有可能没有接收到这个确认报文,就会一直处于LAST-ACK状态,在超时之后B就会重发关闭连接报文,而此时A已经进入CLOSED状态了,就会导致B无法进入CLOSED状态。
而设置了TIME-WAIT状态之后,A会等待2MSL时间,如果B重发了FIN+ACK报文,A还是可以接收到并且发出关闭确认报文,直到B进入CLOSED状态。
原因2:确保A最后发送的报文在网络中消失,MSL表示报文的最长寿命,达到时间报文就会失效,所以A等到2MSL时间之后,报文无论是否被B接收到肯定是会失效,这样就确保了此报文不会影响到下一个新的连接。而如果没有TIME-WAIT状态,而是A直接进入CLOSED状态,然后A又再次和B通过三次握手建立了连接,此时A最后发送的关闭确认报文可能还在网络中传输,就会出现旧的报文段出现的新的连接中。
三、TCP可靠传输
tcp一大特性就是可靠传输,而网络传输过程中,很容易就会出现丢失、重复、错误及延迟的问题,那么TCP能保证数据的传输过程不会丢失、不会重复、不会乱序,是如何达到的呢?主要有以下四点:
3.1、确认和重传机制(ack机制)
TCP连接的双方发送报文之后,必须等待接收方的ACK,否则就认为这个报文丢失了而重传报文,比如发送方发送了报文seq为x,则接收方会返回一个ack=x+1。另外发送方发出报文之后会启动一个计时器(RTO),计时时间到了还没有收到ack就会重新发送。另外接收方还会对接收到的报文进行校验,如果校验不通过会再ack上返回异常的报文seq,这样发送方就会重传这个seq。(ack可以优化成多个报文合并ack一次,只需要ack最后一条报文即可,可以减少ack次数)
3.2、数据排序机制(seq机制)
每条报文都包含一个seq序列号,这个序列号会从初始的seq值上进行递增,如果发送方发送seq=x,则接收方的ack=x+1,然后发送方下一次的报文seq就等于x+1。而如果seq=x+n的报文丢失了,发送方就很清楚是哪一个报文丢失了,从而可以重传。而接收方可以根据seq来对报文进行排序,并且可以丢弃掉重复的报文。
3.3、流量控制(滑动窗口机制)
发送方维持一个滑动窗口来控制发送方报文发送,防止发送方报文发送太快而导致接收方无法及时处理,所以将报文分成四类:
1.发送完成且已经确认的
2.发送完等待确认的
3.等待发送且允许发送的
4.窗口被占满暂时不允许发送的
窗口的左边在1-2类之间,右边在3-4类之间,通过滑动窗口来进行流量控制有三种方法,分别如下:
1.停等协议:窗口大小为1,即每次只可发送一个报文,等确认之后才可发送下一个报文
2.后退N步协议:窗口大小大于1,每次可以发送多个报文,当接收方连续发送三次连续的同一个序号的ack,则表示这个序号的报文丢失了,则发送方从这个序号开始到后面的所有报文都重发一次。比如丢失的是7,那么7后面的8,9,10...都会再重发一次
3.选择重传协议:选择重传是后退N步都优化版,即只重发丢失的报文
3.4、拥塞控制(慢启动、拥塞避免、快速重传、快速恢复)
当网络出现拥塞情况,这时发送方和接收方就会频繁的发生丢包报文以及重发的报文,这样就会使得本来就堵塞的网络变得更加的堵,如果不加控制就可能导致网络崩溃了。所以tcp添加来拥塞控制,通过控制拥塞窗口(cwnd)的大小和拥塞阈值(ssthreshold)的大小来进行拥塞控制
a、慢启动
此时一般是(记住是一般情况)cwnd<ssthreshold,此时cwnd呈指数形式增长,1、2、4、8、16、32...这种增长趋势
b、拥塞避免
此时一般cwnd>ssthreshold,此时cwnd呈线性增长,32、33、34、35...这种增长趋势
c、拥塞解决
此时一般是遇到了网络拥塞的状况,解决方法是拥塞阈值乘性减即ssthreshold=cwnd/2,cwnd=1,或者ssthreshold=cwnd/2,cwnd=ssthreshold,这两种情况在后面说明
d、快速恢复
一般是启用拥塞结局策略之后,根据不同的情况,进入慢启动或者拥塞避免阶段。
浅探网络1---tcp协议详解(三次握手和四次挥手)的更多相关文章
- python网络编程-TCP协议中的三次握手和四次挥手(图解)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- TCP协议中的三次握手和四次挥手(图解)【转】
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...
- 真的懂了:TCP协议中的三次握手和四次挥手(关闭连接时, 当收到对方的FIN报文时, 仅仅表示对方不在发送数据了, 但是还能接收数据, 己方也未必全部数据都发送对方了。相当于一开始还没接上话不要紧,后来接上话以后得让人把话讲完)
一.TCP报文格式 下面是TCP报文格式图: (1) 序号, Seq(Sequence number), 占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2) 确 ...
- python TCP协议详解 三次握手四次挥手和11种状态
11种状态解析 LISTEN -------------------- 等待从任何远端TCP 和端口的连接请求. SYN_SENT --------------- 发送完一个连接请求后等待一个 ...
- 网络编程简介(OSI七层协议,TCP协议原理,三次握手与四次挥手)
目录 网络编程 软件开发架构 C/S架构 B/S架构 网络编程的发展史 互联网协议 1.物理连接层 2.数据链路层 3.网络层 4.传输层 5.应用层 三次握手四次挥手 三次握手建链接 数据传输 四次 ...
- 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协议中的三次握手和四次挥手(图解) 转载
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
随机推荐
- 一次基于Vue.Js的用户体验优化 (vue drag)
一.写在前面 半年以前,第一次在项目上实践VueJs,由于在那之前,没有Angular,avalon等框架的实践经验,所以在Vue的使用上,没有给自己总结出更多的经验和体验.随着项目进行和优化改版,无 ...
- HTTP Status 404(The requested resource is not available)的几种解决方案
1. 未部署Web应用 2.URL输入错误 排错方法:首先,查看URL的IP地址和端口号是否书写正确.其次,查看上下文路径是否正确 Project--------Properties--- ...
- Nginx 日志文件 access_log 详解
Module ngx_http_log_module nginx 日志相关指令主要有两条, 一条是log_format,用来设置日志格式,另外一条是access_log,用来指定日志文件的存放路径.格 ...
- mvc 控制器忽略某些方法
需求:登录信息验证,需要忽略登录注册这些接口的验证,通过给方法加忽略过滤器实现 1.需要忽略的方法加[IgnoreLoginFilter] 2.定义忽略过滤器 public class IgnoreL ...
- Mysql推荐使用规范(转)
一:基础规范 1.使用InnoDB存储引擎 支持事务.行级锁.并发性能更好.CPU及内存缓存页优化使得资源利用率更高 2.推荐使用utf8mb4字符集 无需转码,无乱码风险, 支持emoji表情以及部 ...
- 用lua编写wireshark插件分析自己定义的协议
参见: https://yoursunny.com/study/IS409/ScoreBoard.htm https://wiki.wireshark.org/LuaAPI/TreeItem http ...
- 字符串匹配的 KMP算法
一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...
- Nest.js 拦截器
Docs: https://docs.nestjs.com/interceptors 该对象包含从路由处理程序返回的值 在方法执行之前/之后绑定额外的逻辑 转换函数返回的结果 转换从函数抛出的异常 / ...
- Nestjs 使用mongodb
Docs: https://docs.nestjs.com/techniques/mongodb yarn add @nestjs/mongoose mongoose 链接 // sec/app.mo ...
- background-color:transparent
background-color没有none值 在工作中发现, 这样是没反应的, 要写这个样式才能去掉背景颜色() background-color属性详细链接: http://www.w3sch ...