• [网络] TCP协议是什么?套接字Socket是什么?它们是什么关系?


    前言


    对于TCP协议、套接字Socket,相信我们大部分人对这两个东西或多或少都有耳闻,并且可能会认为它俩就是同一个东西,这实际是一个比较常见的误区,笔者将用本文去梳理TCP与Socket相关的知识来带你了解什么是TCP什么是套接字。

    TCP协议是什么?


    TCP,全称Transmission Control Protocol,中译传输控制协议。和IP协议、JSON格式啊等等一切网络相关的一样,是由IETF组织(Internet Engineering Task Force)在rfc系列里定义的一个网络协议标准。

    TCP位于网络层协议IP协议之上。和UDP协议同层次。虽然这么介绍了,但依然难以理解对不对?
    如果想要理解TCP协议,那么理解IP协议就是有必要的。我们需要先理解一下IP协议是什么?意味着什么?才能帮助我们更好地理解TCP协议。

    IP协议

    IP,全称Internet Protocol,中译互联网协议,通常被称为IP协议。是IETF组织定义的网络层的协议。

    IP协议为我们某个网络下的每个网络设备都规定门牌号(IP地址)以及寻址&路由的规则,这样我们就能通过众多网络设备去找到拥有对应的IP地址的网络设备去“投递”数据。

    网络设备才有“门牌号”(IP地址)

    前面我们提到了IP协议是给网络设备规定了门牌号,这是什么意思呢?

    笔者的意思是PC本身不算网络设备,是没有网络地址的。PC里的 网卡才算是网络设备,有IP地址。那么其实我们通过IP协议传递数据的时候呢,更多的时候是投递到网卡这个硬件上的

    网卡这个我们熟悉的网络硬件设备,更像是我们PC在网络中的邮政局,用于接收和发送数据。

    网卡、网卡驱动与操作系统的关系

    上面一节我们提到了网卡这个网络硬件设备其实是网络数据收发的起始点,IP地址可以说定位的就是我们的网卡。数据发送至网卡这个硬件设备之后,通常这些个数据需要被操作系统进一步处理。

    但是网卡硬件设备的生产商有很多,每一家可能都有不同的指令,那么我们的操作系统(进程)不可能知道如何去和所有种类的网卡硬件做数据交互,于是就有了一种类似Java SPI的委托机制:网卡驱动程序

    网卡驱动程序几乎都是由网卡硬件生产商所开发和提供的。有了这些网卡驱动程序,我们的操作系统进程(OS进程)就可以和对应网卡做数据交互了。

    操作系统进程与TCP协议

    上节我们知道了操作系统可以利用网卡驱动程序从网卡存取数据。那么TCP协议呢,其实就是一种对于从网卡硬件设备取来数据后,如何进一步处理的一种规范。这个规范指引了我们如何实现一个能保证数据传输完整性的传输层组件,实现了TCP协议的组件被称为TCP Peer,笔者本文称其为TCP通信组件,其保证数据传输完整性是通过数据承认和重传机制(acknowledge & retransmit) 来实现的,相对的,同处传输层的UPD协议没有这个机制,所以利用基于UPD协议实现的传输层组件呢,就无法保证数据传输的完整性。这个本文不作深入讨论,如果笔者有兴趣可以搜索关键字:TCP Sequence Number。

    简单来说操作系统利用TCP通信组件,可以 取到完整的外部网络数据向外部发送完整的网络数据

    操作系统进程和Socket套接字

    通过上节,我们知道了操作系统进程内部有实现了TCP协议的组件,通过这个组件能收发“完整”的数据,那么我们都知道这些完整的数据,不可能无限制的存储在我们操作系统进程的内存空间之中。这些数据必须要存储到某个地方,那么廉价地存储方式是什么呢?诶,没错就是硬盘了。

    我们操作系统进程通过TCP组件取到完整数据之后,会把数据存储到硬盘之中。既然是存储到硬盘之中,那就一定会规定文件格式,那么在网络IO之中呢,这种文件被称为Socket,也就是大名鼎鼎的套接字了,所以Socket套接字本质是个特殊的文件,用于存储来自网络的数据。

    用户进程和Socket套接字

    通过上节,我们知道了操作系统通过TCP组件最终把来自网络的数据放到了socket套接字文件之中,那么这些socke套接字文件里的数据需要有其消费者对不对?

    聪明的读者一定已经猜到,这里的数据消费者,就是我们的用户进程了,就比如大家开发的Web应用程序、rpc服务的消费者程序和提供者程序、HTTP Restful API服务器程序等等。

    用户进程如何消费Socket套接字文件里的数据?

    通过上节,我们知道了用户进程是会从Socket套接字文件里消费数据的。那么如何消费数据呢?
    这涉及到文件IO了对不对?那么操作系统层面提供了文件IO的支持。大部分操作系统,都提供了如bio、nio文件io功能(系统库)。

    所以如果你使用偏底层语言如C、C++之类的,你如果想消费Socket文件里的数据,通常是通过调用系统库接口来实现,如大名鼎鼎的epoll等等。
    如果你使用高级编程语言如Java,你如果想消费Socket文件里的数据,可以使用JDK里特定的类,这些类呢通过JNI(Java Native Interface)调用C、C++编写的方法,这些方法里依然是通过调用系统库接口来实现的,不过是被包装了一层而已。

    TCP协议与Socket的区别?


    读到这里,相信大家已经能够理解:

    1. TCP协议是一个标准,通常由操作系统根据这个TCP协议标准开发通信组件,这个通信组件被操作系统管理,其数据的上下游分别是Socket套接字和网卡。

    2. Socket是一个文件,操作系统通过TCP通信组件(TCP Peer)收发数据,接收到的数据会放到Socket文件里,用户进程则通过操作系统提供的文件IO接口,从Socket文件里读写数据。

    至此,我们应该能对网络数据的接收过程大致有一个比较全面的理解了。

    用户进程接收和发送网络数据的过程

    在本节,笔者简单地展示一下用户进程是如何接收和发送网络上的过程。参考下图:

    • 接收数据:网卡 → 网卡驱动 → OS进程里的TCP通信组件 → Socket文件 → 用户进程
    • 发送数据:用户进程 → Socket文件 → OS进程里的TCP通信组件 → 网卡驱动 → 网卡
      在这里插入图片描述

    Socket文件与TCP连接数

    通过上一章节我们也看到,用户进程可以打开不止一个Socket文件,在TCP的工作流程里,TCP连接与Socket文件与TCP端口是一一对应的。这意味着如果一个接近终端用户服务器在被大量外部用户同时连接时,6万多个TCP连接资源会非常容易耗尽,这也是为什么我们需要做服务器集群的原因之一。当然这是与终端用户最接近的服务器通常会面临的问题,企业内部服务器(位于内网的服务器)则一般不会面对TCP连接资源耗尽的问题。

    结语


    TCP协议是当今互联网最重要的基础设施之一,正确理解TCP协议与操作系统进程、Socket文件、网卡和用户进程之间的关系,对于帮助我们去理解当今越来越复杂的企业系统架构会非常有帮助。

    本文是一篇类似于杂谈的文章,操作系统种类繁多,笔者无法去验证所有实现细节,希望笔者们带着批判的去阅读本文。如果有错误的地方,也希望大家帮忙指正。

    我是虎猫,希望本文对你有帮助。(=・ω・=)

  • 相关阅读:
    illustrator插件-什么是脚本-如何使用-什么是动作-AI插件
    (Java高级教程)第一章Java多线程基础-第一节4:synchronized关键字(监视器锁monitor lock)和volatile关键字
    CV相关 - 文献地址地址、数据集地址
    深入理解隔离性(MVCC,快照,undo log,Read View)
    Java基于基于Springboot+vue的药品销售商城网站 在线购药 elementui毕业设计
    电影售票系统遇到的问题
    Servlet【 ServletAPI中的会话管理Cookie与Session】
    高效复用:RecyclerView内部嵌套横向列表时的优化技巧
    03.前后端分离中台框架 zhontai 项目代码生成器的使用
    数据库相关概念复习--个人复习使用
  • 原文地址:https://blog.csdn.net/ToraNe/article/details/128065086