TCP协议通讯流程(三次握手及四次挥手)

文章目录

  • TCP协议通讯流程(三次握手及四次挥手)
    • 一、服务器端
    • 二、客户端
    • 三、三次握手四次挥手
    • 三、具体流程
    • 四、相关注意事项

一、服务器端

  1. 调用socket函数,创建一个socket(文件描述符)操作句柄
  2. 调用bind函数,把刚创建的socket文件描述符 和 ip及端口 绑定在一起,注意一个进程可以绑定多个端口号,但是一个端口号只能被一个进程绑定bind中进程和端口的关系
  3. 调用listen函数,对socket文件描述符进行监听(首先listen会在进程地址空间中维护一个缓冲区,如果有客户链接进来,就把其放进缓冲区)
  4. 进入主循环,循环处理客户端的请求(死循环)
  5. 调用accept函数并阻塞,等待客户端进来链接(在listen缓冲区中去出),accept成功就返回一个新的socket文件描述符操作句柄,在多进程或多线程等情况下,旧的socket在父进程中返回,继续accept,子进程拿到newsocket对客户进行操作(下面的操作都是newsocket)
  6. 调用recv函数,接受客户端发送的请求
  7. 对客户端发送来的请求在函数内部进行处理
  8. 调用send函数,把处理结果返回给客户端。
  9. 关闭socket

二、客户端

  1. 调用socket函数,创建一个socket(文件描述符)操作句柄
  2. 调用connect函数,向服务器发送链接请求
  3. 进入主循环,服务器和客户端可能进行多次交互,不止一次
  4. 调用send函数,把请求数据发送给服务器
  5. 调用recv函数,接受服务器返回的结果
  6. 关闭socket

三、三次握手四次挥手

  • 1 . 三次握手

  • 在客户端向服务器建立链接的过程中:客户端首先创建自己的socket

  • 调用connect发起链接服务器的请求

  • 其中connect函数会发出SYN段并阻塞等待服务器的响应 (第一次)

  • 服务器收到客户端的链接请求SYN,会应答客户端,向客户端发送一个SYN-ACK,表示同意建立连接请求 (第二次)

  • 客户端收到服务器端的SYN-ACK后会从connect返回,同时向服务器端再应答一个ACK段; (第三次

  • 2.四次挥手

  • 在数据传输的过程中:建立连接后,TCP协议提供全双工的通信服务(全双工:在同一条链接中,同一时刻通信双方都可以写数据)。

  • 服务器在调用socket创建出socket文件描述符后,再调用bind绑定ip及端口号,服务器在调用accept获取客户端,调用完accept后立即调用recv函数(阻塞,跟read读取管道一样)

  • 在这个时间客户端调用send函数向服务器端发送请求(和write管道一样),服务器收到从recv返回的请求,在对客户端的请求进行处理,在这期间客户端调用send函数阻塞等待

  • 服务器端调再用send把响应结果发给客户端,再次调用recv读取客户端请求

  • 在断开链接的过程中(一般都是客户端主动断开链接,服务器毕竟不是为一个客户服务):如果客户端不在请求了,就会调用close函数关闭链接,客户端就会向服务器端发送一个FIN段,表示我要断开链接了 (第一次)

  • 此时服务器端在响应完客户端的请求后,没有在收到客户端的请求,一直阻塞在recv处,此时收到客户端发送的FIN后,会向客户端回应一个ACK,同时recv会返回0 (第二次)

  • 服务器端recv返回后,服务器端就直到客户端要关闭链接了,也调用close函数关闭连接,再向客户端发送一个FIN (第三次)

  • 客户端收到ACK和FIN后,再向服务器端发送一个ACK (第四次)

三、具体流程

  • 服务端状态转化:
  • [CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态, 等待客户端连接;
  • [LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文.
  • [SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文ACK, 就进入ESTABLISHED状态, 可以进行读写数据了
  • [ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器返回确认报文段ACK并进入CLOSE_WAIT;
  • [CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)
  • [LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接
  • 客户端状态变化
  • [CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
  • [SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态冰箱服务器端发送一个ACK, 开始读写数据;
  • [ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段FIN, 同时进入FIN_WAIT_1;
  • [FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
  • [FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
  • [TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(MaxSegment Life, 报文最大生存时间)的时间, 才会进入CLOSED状态

四、相关注意事项

  • 1 . 客户端为什么不需要bind?

  • 首先服务器端bind是因为如果客户端要访问服务器端,就必须要服务器端端“地址”,也就是ip+端口号,这样客户端才能找到服务器,进行通信

  • 如果服务器端不进行bind操作,那么操作系统就会随机分配端口号给服务器,那么客户端就不能和服务器端进行通信。

  • 而客户端为什么不需要bind,是因为如果客户端bind一个ip + 端口,那么如果一个pc上有多个用户,那么bind同一个端口就会出错(如果一台pc上只有一个用户也是可以bind)

  • 2 . 为什么要进行三次握手?

  • 为了防止无效的连接请求报文到达服务器而引起错误。

  • TCP发起建立连接的一方不会一直等待对方的回复,如果超时,他再次发起这个请求,上一个作废。

  • 假设A给服务器发送了一个请求,但是由于网络原因迟迟没有到达B服务器。由于一直没收到服务器端的回复确认,所以就进行超时重传,上个就舍弃了。

  • 然后新的请求很快的到达了B服务器,然后B服务器也很快的进行了响应,如果是两次握手的话,这样就建立了连接

  • 但是上次因网络问题迟迟未到的第一个请求这时到达了B服务器,服务器依然会当成新的连接请求进行响应,(服务器只要响应,第二次握手就完成了)这时又会建立连接,这就会出现建立了两个连接的局面,

  • 然后这就会出现很多问题,例如服务器端认为完成了握手,可以发送数据了,于是一直处于等待数据状态,而发送端不理睬服务器端发来的请求(因为发送端的那个请求早就被清除了),不去发送数据,后果就是服务器一直等,这样就会浪费很多服务器资源

  • 如果是三次握手的话,就会避免这个问题,因为比如第二次的新请求到达时,发送端就会又给服务器端发送个确认请求,表示接收到了,这样迟到的那个请求到达服务器端,然后返回到发送端时,发送端并不会响应。然后这个连接并不会建立,服务器也就不会白白等待。

  • 3.为什么要进行四次挥手?

  • 确保数据能够完整传输。

  • 当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。

  • 但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,(按照常理的话,第二次和第三次挥手应该一起回复FIN和ACK的,但是因为服务器端可能有数据没发完,所以不能也立刻去主动申请关闭,所以要把ACK和FIN分开)再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。

  • 4.timewite的产生的原因及作用?

  • 为实现TCP全双工连接的可靠释放

  • 假设发起主动关闭的一方(client)最后发送的ACK在网络中丢失,由于TCP协议的重传机制,执行被动关闭的一方(server)将会重发其FIN

  • 在该FIN到达client之前,client必须维护这条连接状态,也就说这条TCP连接所对应的资源(client方的local_ip,local_port)不能被立即释放或重新分配

  • 直到另一方重发的FIN达到之后,client重发ACK后,经过2MSL时间周期没有再收到另一方的FIN之后,该TCP连接才能恢复初始的CLOSED状态。

  • 如果主动关闭一方不维护这样一个TIME_WAIT状态,那么当被动关闭一方重发的FIN到达时,主动关闭一方的TCP传输层会用RST包响应对方,这会被对方认为是有错误发生,然而这事实上只是正常的关闭连接过程,并非异常

  • 确保第四次握手时发送方发送的ACK可以到达接收方 如果2MSL时间内没有收到,则接收方会进行重发

  • 确保当前连接的所有报文都已经过期(每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间,2MSL足够使所有报文过期了)

  • 5.理解close_wait状态?

  • close_wait状态介绍:

  • 客户端主动关闭连接,服务器接收到客户端的FIN,但是还没有发送自己的FIN,此时的状态为close_wait状态,大量的close_wait状态拖累服务器性能

  • close_wait产生的原因:

  • 某种情况下客户端关闭了连接,但是我方忙于读写,没有关闭连接

  • 解决方法:

  • 思想:检查出客户端已经关闭的连接,他之所以会出现这种问题,肯定是服务器端的连接释放的代码存在问题

1.当服务器读写失败时,可以选择关闭连接2.定期向连接发送询问数据,检查收到的回复数据包(Heart-Beat线程发送指
定格式的心跳数据包)3.修改keep-live参数(超时时间,tcp检查间隔时间:keeplive探测包
发送的间隔,tcp检查次数:如果对方不予应答,探测包发送的次数)

TCP协议通讯流程(三次握手及四次挥手)相关推荐

  1. Python常见面试题:TCP 协议中的三次握手与四次挥手相关概念详解

    今天来聊聊Python常见面试题中面试频率特别高的一个题目:TCP 协议中的三次握手与四次挥手. 涉及到的知识点有: 1.TCP.UDP 协议的区别 2.TCP 头部结构 3.三次握手与四次挥手过程详 ...

  2. tcp协议报文和三次握手与四次挥手

    tcp协议: tcp是面向连接.可靠的进程到进程之间的协议.tcp提供全双工服务:即:数据可在同一时间双向传输. tcp报文段首部格式: 各字段含义: 源端口号:16位字段,为发送端进程对应的端口号 ...

  3. 【转载】万字详文彻底弄懂TCP协议:从三次握手和四次挥手说起

    今日头条 腾讯技术工程 作者:morganhuang,腾讯 IEG 后台开发工程师 说到 TCP 协议,相信大家都比较熟悉了,对于 TCP 协议总能说个一二三来,但是 TCP 协议又是一个非常复杂的协 ...

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

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

  5. Linux疑难杂症解决方案100篇(十九)-什么是TCP协议中的“三次握手,四次挥手”?带你深入探讨下

    前言 以下是博主精心整理的专栏,需要的小伙伴可自行订阅. 深度学习100例全系列详细教程  深度学习算法原理介绍及应用案例 tensorflow从入门到精通100讲 深度学习框架TensorFlow的 ...

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

    最近在复习计算机网络,看到TCP这一章,总结一下. 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 1.jpg 先来看看如何建立连接的: 2.png 首先Client端 ...

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

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

  8. 大白话了解TCP协议:经典——三次握手数据传输 四次挥手

    一直在想如何去描写这个过程,希望用最简单的话加入到自己博客之中 本来开了个小店,但是还是想了一下取消了,技术分享不能以盈利为目的 干嘛要我和她握手呀? TCP是一个就是靠着连接起家的服务协议. 我们已 ...

  9. TCP协议中的三次握手和四次挥手(图…

    http://m.blog.csdn.net/article/details?id=51793861 http://m.blog.csdn.net/article/details?id=6667471

  10. tcp 协议中发送窗口的大小应该是_TCP 协议中的三次握手与四次挥手

    今天来聊聊面试频率特别高的一个题目:TCP 协议中的三次握手与四次挥手.涉及到的知识点有: 1.TCP.UDP 协议的区别 2.TCP 头部结构 3.三次握手与四次挥手过程详解 4.什么是 TIME_ ...

最新文章

  1. rdd转换成java数据结构_如何将CSV文件转换为RDD
  2. Apache Thrift快速入门教程
  3. React学习初探(环境搭建)
  4. Windows下安装solr步骤详解
  5. php服务器端注释,php标识和注释
  6. 2020年不能启动win7_包装车间2020年大修正式启动
  7. YOLO算法原理详解
  8. 消灭非稳态噪音的利器 - AI 降噪
  9. vue路由守卫(页面鉴权)
  10. 考研英语近义词与反义词·十四·总篇
  11. 高中生学python培养思维能力_Python教学:编程如何培养学生计算思维
  12. 评价的等级优良差_小学生期末评语-等级优良合格(最佳版本)
  13. 思维导图怎么画:这款免费思维导图软件推荐给你
  14. 详细解析Java多态、向上转型、向下转型
  15. HTML京东快报页面,京东快报.html
  16. 一台计算机只能注册一台sql,局域网中的一台电脑为啥连接不到另一台电脑中的SQL远程数据库...
  17. 如何去管理正在运行的程序和服务
  18. 专题一:欧拉视频放大(线性)------MATLAB代码解析(二.amplify_spatial_lpyr_temporal_iir())
  19. TI处理器EDMA的三种触发方式与通道
  20. 整体橱柜效果图软件测试,整体橱柜怎么设计 整体橱柜效果图欣赏

热门文章

  1. qt撤销与回退_Qt动画框架
  2. free: seconds argument `1‘ failed
  3. 大数据(1) - 虚拟机集群搭建
  4. Java集合--TreeMap
  5. Puppet exec资源介绍(二十六)
  6. varnish缓存服务器构建疑问
  7. ALV打印不显示打印界面的问题
  8. Java 调用Dll
  9. 【Java数据结构】3.1 顺序栈
  10. 一步一步学习 iOS 6 编程(第四版)正式发布!