专栏首页用户4352451的专栏深入浅出TCP/IP协议

深入浅出TCP/IP协议

什么是TCP/IP协议?

TCP/IP 是一类协议系统,它是用于网络通信的一套协议集合.传统上来说 TCP/IP 被认为是一个四层协议

1. TCP/IP协议模型?

通过图上我们可以知道TCP/IP是一个协议集合,且其模型是四层模型: 应用层,传输层, 网络层, 网络接口层。于是我们知道TCP/IP协议不是单指的是TCP 和 IP,而是一个协议系统。但单独的TCP就是网络层的TCP,IP就是传输层的IP

2.TCP/IP协议的系统是如何工作的?

  1. 上图清楚地表示了TCP/IP协议中每个层的作用,而TCP/IP协议通信的过程其实就对应着数据入栈与出栈的过程。入栈的过程,数据发送方每层不断地封装首部与尾部,添加一些传输的信息,确保能传输到目的地。出栈的过程,数据接收方每层不断地拆除首部与尾部,得到最终传输的数据。

4. TCP 和 UDP 的区别?

传输层提供了两种到达目标网络的方式

  • 传输控制协议(TCP):提供了完善的错误控制和流量控制,能够确保数据正常传输,是一个面向连接的协议。
  • 用户数据报协议(UDP):只提供了基本的错误检测,是一个无连接的协议。

特点: 1)UDP: 把数据打包 数据大小有限制(64k) 不建立连接 速度快,但可靠性低

2)TCP: 建立连接通道 数据大小无限制 速度慢,但是可靠性高

5. TCP是如何保证可靠性的?

TCP协议保证数据传输可靠性的方式主要有: (https://blog.csdn.net/liuchenxia8/article/details/80428157详细解释)

  1. 校验和
  2. 序列号
  3. 确认应答
  4. 超时重传
  5. 连接管理
  6. 流量控制
  7. 拥塞控制

3. TCP的三次握手和四次挥手?

TCP的三次握手?建立连接和四次挥手?断开连接,相信很多人都听说过,也都看过相关的内容,本篇是为了记录自己对与这两种操作的理解。 在进入正式内容之前,先来看几个符号的概念:

  • 序列号seq: 用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
  • 确认号ack: 期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
  • 确认ACK: 仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
  • 同步SYN: 连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
  • 终止FIN: 用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
三次握手

首先进入一下情景: 我正在饭店里和朋友吃饭,喝的正嗨的时候,女朋友打电话过来,饭店里有很多人,环境原因听不太清电话里的声音:

  • 我:能听到我的声音吗?
  • 女:能听到,大点声,你能听到我讲话吗?
  • 我:能听到, 如此这般,才能保证双方都能听到声音,才能继续对话呀。

TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP 协议提供可靠的连接服务,连接是通过三次握手?进行初始化的。三次握手?的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。由此我们来对应客户端与服务器之间的建立连接:

  • 第一次握手?: 客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN=1,同时随机生成初始序列号 seq=x,此时,客户端进程进入了 SYN-SENT状态,等待服务器的确认。
  • 第二次握手?: 服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己随机初始化一个序列号 seq=y,此时,服务器进程进入了SYN-RCVD状态,询问客户端是否做好准备。
  • 第三次握手?: 客户端进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,此时,连接建立,客户端进入ESTABLISHED状态,服务器端也进入ESTABLISHED状态。

那么问题来了?那为什么要进行三次握手?

假如现在客户端想向服务端进行握手,它发送了第一个连接的请求报文,但是由于网络信号差或者服务器负载过多,这个请求没有立即到达服务端,而是在某个网络节点中长时间的滞留了,以至于滞留到客户端连接释放以后的某个时间点才到达服务端,那么这就是一个失效的报文,但是服务端接收到这个失效的请求报文后,就误认为客户端又发了一次连接请求,服务端就会想向客户端发出确认的报文,表示同意建立连接。

假如不采用三次握手,那么只要服务端发出确认,表示新的建立就连接了。但是现在客户端并没有发出建立连接的请求,其实这个请求是失效的请求,一切都是服务端在自相情愿,因此客户端是不会理睬服务端的确认信息,也不会向服务端发送确认的请求,但是服务器却认为新的连接已经建立起来了,并一直等待客户端发来数据,这样的情况下,服务端的很多资源就没白白浪费掉了。采用三次握手的办法就是为了防止上述这种情况的发生,比如就在刚才的情况下,客户端不会向服务端发出确认的请求,服务端会因为收不到确认的报文,就知道客户端并没有要建立连接,那么服务端也就不会去建立连接,这就是三次握手的作用。

四次挥手

来,再次进入以下情景: 假如有一天我想要自由了,我就跟我的女朋友提出分手的要求:

  • 我:我要自由,自由万岁,分手吧
  • 女:好,你要分手是吧 然后她会骂我渣啊来发泄,或者试图挽留,在经过冷静之后:
  • 女:那就这样吧,分
  • 我:好的,分

至此就各奔东西,互相安好,相忘于江湖。 当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,为了防止资源浪费肯定要断开TCP连接,那对于TCP的断开连接,这里就有了断开连接的四次挥手。

  • 第一次挥手?: 客户端进程发出连接释放FIN报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=x,此时,客户端进入FIN-WAIT-1(终止等待1)状态。
  • 第二次挥手?: 服务端进程收到连接释放FIN报文,发出确认ACK报文,ACK=1,ack=x+1,并且带上自己的序列号seq=y,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。此时,服务端通知高层的应用进程,客户端向服务端的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务端若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。客户端收到服务端的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文,在这之前依然可以接收服务端发送过来的最后的数据。
  • 第三次挥手?: 服务端将最后的数据发送给客户端完成后,就向客户端发送连接释放FIN报文,FIN=1,ack=x+1,此时的序列号为seq=z,此时,服务端就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  • 第四次挥手?: 客户端接收到服务端的连接释放FIN报文后,必须发出确认报文,ACK=1,ack=z+1,而自己的序列号是seq=x+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。此时服务端收到客户端发送过来的确认报文,就立即撤销自己的传输控制块TCB,进入CLOSED状态,注意此时的TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,客户端没有收到服务端发来的任何数据,证明服务端已正常关闭,此时客户端会撤销相应传输控制块TCB后,进入CLOSED状态。至此,TCP的连接才真正的断开了。(服务端结束TCP连接的时间要比客户端稍微早一些)
为什么断开连接需要四次挥手?呢,像建立连接的时候一样,三次行不行呢?
  • TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工 模式,这就意味着,在客户端想要断开连接时,客户端向服务端发送FIN报文,只是表示客户端已经没有数据要发送了,但是这个时候客户端还是可以接收来自服务端的数据。
  • 当服务端接收到FIN报文,并返回ACK报文,表示服务端已经知道了客户端要断开连接,客户端已经没有数据要发送了,但是这个时候服务端可能依然有数据要传输给客户端。
  • 当服务端的数据传输完之后,服务端会发送FIN报文给客户端,表示服务端也没有数据要传输了,服务端同意关闭连接,之后,客户端收到FIN报文,立即发送给客户端一个ACK报文,确定关闭连接。在之后,客户端和服务端彼此就愉快的断开了这次的TCP连接。
  • 或许会有疑问,为什么服务端的ACK报文和FIN报文都是分开发送的,但是在三次握手的时候却是ACK报文和SYN报文是一起发送的,因为在三次握手的过程中,当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是在关闭连接时,当服务端接收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,你发的FIN报文我收到了,只有等到服务端所有的数据都发送完了,才能发送FIN报文,因此ACK报文和FIN报文不能一起发送。所以断开连接的时候才需要四次挥手来完成

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用Vavr进行函数式编程(二)

    居士
  • 请分清楚Java内存区域和Java内存模型

    java内存区域是java虚拟机在执行java程序的时候会把它所管理的内存进行划分不同的数据区域。 但是java内存模型是为了屏蔽各种硬件和操作系统的内存访问...

    居士
  • redis的持久化存储RDB的原理分析

    想到redis,你的第一反应是什么呢?redis很快,我们一般一用它做缓存,再想想他为什么快呢?也许你的第一反应和我的第一反应是一样的,因为他是基于内存存储的,...

    居士
  • 硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

    不管面试 Java 、C/C++、Python 等开发岗位, TCP 的知识点可以说是的必问的了。

    小林coding
  • 一文搞懂什么是TCP/IP协议

    原文:https://blog.csdn.net/petterp/article/details/102779131

    全栈自学社区
  • TCP详解+wireshark抓包演示简介

    TCP提供了一种面向连接的、可靠的字节流服务。 面向连接:接双方在通信前需要预先建立一条连接,这犹如实际生活中的打电话。

    用户2929716
  • 压力测试遭遇大量TIME_WITE之后

    前语:http协议是互联网中最常使用的应用层协议,它的绝大多数实现是基于TCP协议的。 一 问题描述 某天,在对一个提供http接口的后台服务进行压力测试过程中...

    腾讯移动品质中心TMQ
  • 我理解的 TCP 连接

    TCP 是面向连接的协议。运输连接是用来传输 TCP 报文的。TCP 运输连接的建立和释放是每一次面向连接通信中必不可少的过程。因此,运输连接有三个阶段,即:连...

    haifeiWu
  • 30.1. 企业级开发进阶2.1:TCP编程

    农历五月初二 宜 抽烟 抽烟有利于提神,增加思维敏捷 晚上加班 晚上是程序员精神最好的时候

    大牧莫邪
  • 【网络协议】TCP连接的建立和释放

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/29382883

    bear_fish

扫码关注云+社区

领取腾讯云代金券