当前位置: 首页 > news >正文

【Linux 25】网络套接字 socket 概念

文章目录

  • 🌈 一、IP 地址概念
    • ⭐ 1. IP 地址的作用
    • ⭐ 2. 源 IP 地址和目的 IP 地址
  • 🌈 二、端口号概念
    • ⭐ 1. 源端口号和目的端口号
    • ⭐ 2. 端口号范围划分
    • ⭐ 3. 端口号 VS 进程 ID
    • ⭐ 4. 套接字 socket 的概念
  • 🌈 三、传输层的典型代表协议
    • ⭐ 1. TCP 协议
    • ⭐ 2. UDP 协议
    • ⭐ 3. 如何选择 TCP 还是 UDP
  • 🌈 四、网络字节序
    • ⭐ 1. 网络中的大小端
    • ⭐ 2. 网络字节序采用大端方式存储
    • ⭐ 3. 网络字节序与主机字节序之间的转换
  • 🌈 五、socket 编程接口
    • ⭐ 1. socket 常见函数
    • ⭐ 2. sockaddr 结构介绍

🌈 一、IP 地址概念

⭐ 1. IP 地址的作用

  • 互连网上的每台主机都有一个唯一的 IP 地址,总的来说就是,IP 地址在网络中用来标识主机的唯一性

⭐ 2. 源 IP 地址和目的 IP 地址

  • 如果想将一台主机 A 的数据传输到另一台主机 B 上,发送数据的 A 主机的 IP 地址就是源 IP 地址,而接受数据的对端主机 B 的 IP 地址就应该作为该数据传输时的目的 IP 地址。
    • 例:唐僧取经时,会根据他所持有的源 IP 地址 (东土大唐) 以及目的 IP 地址 (西天),在取经路上不停的问路,中间走过的每一站都是为了更加靠近目的 IP 地址。
    • 只要有了 IP 地址,数据报文就不会走进不在源 IP 地址和目的 IP 地址之间的其他局域网。
  • 在数据进行传输前,会先自定向下贯穿网络协议栈完成数据的封装,其中在网络层封装的 IP 报头中就包含了该数据的源 IP 地址和目的 IP 地址。

🌈 二、端口号概念

⭐ 1. 源端口号和目的端口号

  • 主机之间进行通信并不仅是为了将数据发送给对端主机而已,那没有任何意义。主机之间进行通信是为了访问对端主机上的某个服务。
    • 用户 a 在 A 主机上使用 qq 给用户 b 的主机 B 中的 qq 发送数据,不是就将这段数据发给主机 B 就完了。
    • 通信的根本目的是为了实现人与人之间的通信,用户 a 从 qq 上发送给用户 b 的消息,需要让用户 b 也能在 qq 上看到才行。
    • 但是用户手里的主机上有那么多进程,没人知道发送的数据应该交给主机上的哪个进程。
    • 同时,如果用户 b 想要给用户 a 回消息,发送的数据也需要能够找到用户 a 手里的主机中的 qq 这个程序才行。
  • 因此,端口号是用来唯一标识主机中的进程
  • 真正的通信是两个主机上的两个进程在进行通信,而源端口号和目的端口号就是用来找到通信双方的主机中的那个用来通信的进程

image-20241026103730933

⭐ 2. 端口号范围划分

  1. 知名端口号 (0 ~ 1023),像 HTTP、FTP、SSH 等广泛使用的应用层协议的端口号都是固定的。
    • 这些端口号和其提供的服务基本上已经算是一个东西了,只要知道这些端口号,就能知道对应提供的是什么服务。
    • 就像 120、110、119 这些电话和与其绑定的服务一样,看到这些电话就知道对应的是啥服务。
  2. 操作系统动态分配端口号 (1024 ~ 65535),由操作系统动态分配的端口号,客户端进程的端口号由操作系统从这个范围分配。

⭐ 3. 端口号 VS 进程 ID

  • 端口号和进程 IP 都能用来唯一标识一台主机上的某个进程,但在网络通信中,并不能用进程 ID 来替代端口号

1. 为什么不能用进程 PID 替代网络端口号 port

  1. 端口号属于网络的概念,进程 ID 用来标识系统内进程的唯一性,它属于系统级的概念;而端口号用来标识需要对外进行网络数据请求的进程的唯一性,它属于网络的概念。
  2. 不是所有的进程都要进行网络通信,一台主机上存在着 n 个进程,但不是所有的进程都要进行网络通信的,但每个进程都要有自己的 PID。这种情况下就不太适合使用 PID 来标识网络进程的唯一性了。
  3. 专事专办,在不同的场景下可能需要不同的编号来标识某种事物的唯一性,某些编号会更加适用于某种场景。
    • 如:身份证号已经足够标识身份的唯一性了,但还是有学号和工号这种特殊编号用来标识在不同场景下的唯一身份。
  4. 实现系统和网络的解耦 (最重要),进程在每次启动时,进程 PID 都会发生变化。如果使用 PID 代替端口号,会直接导致网络部分也需要作出调整。

2. 如何通过端口号 port 找到对应的进程

  • 在底层中,采用哈希的方式建立了端口号和进程 PID 之间的映射关系
  • 当底层拿到端口号时,就可以执行对应的哈希算法,然后拿到与该端口号对应的进程 PID,从而找到对应进程。

⭐ 4. 套接字 socket 的概念

  • IP 地址用来标识网络中唯一的一台主机,而端口号 port 则用来标识该主机上唯一的一个网络进程。
    • 因此,使用 ip + port 就能标识互联网中唯一的一个进程
  • 网络通信,本质上是在用两个互联网进程代替人来进行通信,通过 { 源 ip,源 port,目的 ip,目的 port } 即可标识互联网中唯二的两个进程。
    • 因此,网络通信的本质就是进程间通信
  • 将 ip + port 的组合叫做 socket 套接字

理解 socket 这个名词

  • socket 翻译成中文有 ⌈ 插座 ⌋ 的意思,插座上有不同规格的插孔,将插头插入到对应的插孔当中就能够实现电流的传输。
  • 在进行网络通信时,客户端就相当于插头,服务端就相当于一个插座,但服务端上可能会有多个不同的服务进程 (多个插孔)。因此当访问服务时需要指明服务进程的端口号 (对应规格的插孔),才能享受对应服务进程的服务。

🌈 三、传输层的典型代表协议

  • 网络协议栈贯穿整个网络体系结构,在应用层中,操作系统层和驱动层各自占有一部分网络协议。
  • 传输层写在操作系统中,当使用系统提供的接口实现网络通信时,必须要面对的就是传输层的协议,传输层最典型的协议是 TCP 和 UDP 。

⭐ 1. TCP 协议

  • 传输控制协议 TCP (Transmission Control Protocol) 是一种面向连接的可靠的基于字节流的传输层通信协议。

TCP 协议的特点

  1. TCP 协议是面向连接的:当两台主机之间想要进行数据传输时,需要先建立连接。只有在连接建立成功后才可以进行数据传输。
  2. TCP 协议是保证可靠的:数据在传输过程中如果出现了丢包、乱序等情况,TCP 协议都有对应的解决办法。

⭐ 2. UDP 协议

  • 用户数据报协议 UDP (User Datagram Protocol) 是一种无需建立连接的不可靠的面向数据包的传输层通信协议。

UDP 协议的特点

  1. UDP 协议不需要建立连接:当两台主机想要进行数据传输时,直接将数据包发送给对端主机即可。
  2. UDP 协议是不保证可靠的:由于特点 1,UDP 协议是不可靠的。UDP 协议不知道数据在传输过程中是否出现了丢包、乱序等情况。

⭐ 3. 如何选择 TCP 还是 UDP

1. 不应将 UDP 协议的特点当作缺陷

  • UDP 不保证可靠并不是缺陷,而是特点。
  • UDP 不保证可靠意味着要做的工作比 TCP 少,实现起来比 TCP 简单,且数据传输速度更快。

2. 如何选择通信协议

  • 编写网络通信代码时,应根据上层的应用场景选择 TCP / UDP 协议。
  • 当应用场景严格要求数据在传输过程中的可靠性时,选择 TCP 协议。
  • 当应用场景允许数据传输出现少量丢包时,优先选择简单的 UDP 协议。

🌈 四、网络字节序

⭐ 1. 网络中的大小端

  • 大端模式:数据的高位字节处的内容存放在内存的低地址处,而数据的低位字节处的内容存放在内存的高地址处。
  • 小端模式:数据的高位字节处的内容存放在内存的高地址处,而数据的低位字节处的内容存放在内存的低地址处。

image-20241026152047117

⭐ 2. 网络字节序采用大端方式存储

  • 如果程序只在本地机器上运行,由于同一台机器的数据的存储方式一致,因此无需考虑数据的大小端存储问题。
  • 如果程序涉及到网络通信,则需要考虑大小端的转换问题,否则接收端主机识别出的数据可能与发送端发送的数据不一致。
  • 由于不能保证通信双方存储数据的方式一致,那么就只能统一网络字节序,TCP / IP 协议规定,网络数据流采用大端字节序
    • 如果 发送端 是 小 端存储,需要先将数据转换成大端,然后发送到网络中。
    • 如果 发送端 是 大 端存储,可以直接将数据发送到网络中。
    • 如果 接收端 是 小 端存储,需要先将接收到的数据转换成小端,然后进行识别。
    • 如果 接收端 是 大 端存储,可以直接识别通过网络传输过来的数据。

⭐ 3. 网络字节序与主机字节序之间的转换

  • 为了让网络程序具备可移植性,使得同样的 C 代码在 大端 / 小端 机上都能运行,系统提供了4 个函数用于实现网络字节序和主机字节序之间的转换。
#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);	// 将 32 位的 主机字节序 转换为 32 位的 网络字节序
uint16_t htons(uint16_t hostshort);	// 将 16 位的 主机字节序 转换为 16 位的 网络字节序
uint32_t ntohl(uint32_t netlong);	// 将 32 位的 网络字节序 转换为 32 位的 主机字节序
uint16_t ntohs(uint16_t netshort);	// 将 16 位的 网络字节序 转换为 16 位的 主机字节序
  • 函数名看着挺混乱,但还是有规律的,h 表示 host,n 表示 network,l 表示 32 位长整数,s 表示 16 位短整数。
    • 例:htonl 表示的就是将 32 位的主机字节序转换成 32 位的网络字节序,其余同理。
  • 如果主机采用的是小端存储方式,这些函数就会将提供参数做相应的大小端转换,然后返回转换后的大端字节序。
  • 如果主机采用的是大端存储方式,这些函数就不会进行转换,而是直接将参数返回。

🌈 五、socket 编程接口

⭐ 1. socket 常见函数

  1. 创建套接字
int socket(int domain, int type, int protocol);
  1. 绑定端口号
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
  1. 监听套接字
int listen(int sockfd, int backlog);
  1. 接受请求
int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
  1. 建立连接
int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);

⭐ 2. sockaddr 结构介绍

  • socket 不仅支持跨网络的进程间通信,还支持本主机的进程间通信。
  • 在创建套接字时,需要选择创建的是用于网络通信的网络套接字,还是用于本地通信的域间套接字。
  • 由于在进行网络通信时,需要传递 ip + port,而本地通信则不需要。因此套接字就提供了用于网络通信sockaddr_in 结构体,以及用于本地通信sockaddr_un 结构体。
  • 而为了让网络通信和本地通信都能使用同一个函数,又出现了一种新的结构体 sockaddr,这 3 种结构体的前面 16 个比特位相同,都叫做协议家族。
struct sockaddr_in
{__SOCKADDR_COMMON (sin_);	in_port_t sin_port;			// 端口号struct in_addr sin_addr;	// IP 地址/* Pad to size of `struct sockaddr'.  */unsigned char sin_zero[sizeof (struct sockaddr)- __SOCKADDR_COMMON_SIZE- sizeof (in_port_t)- sizeof (struct in_addr)];
};

image-20241026160322445

  • 在使用 socket 相关函数时,不管要进行的是网络通信还是本地通信,统一传入 sockaddr 结构体作为 socket 相关函数的参数。
  • 通过设置 sockaddr 的协议家族来决定进行的是网络通信还是本地通信,socket 相关函数会提取出 sockaddr 的前 16 个比特位来判断要进行的是本地还是网络通信。
  • 在使用 socket 相关函数时,不管要进行的是网络通信还是本地通信,统一传入 sockaddr 结构体作为 socket 相关函数的参数。
  • 通过设置 sockaddr 的协议家族来决定进行的是网络通信还是本地通信,socket 相关函数会提取出 sockaddr 的前 16 个比特位来判断要进行的是本地还是网络通信。
  • 编写网络通信代码时,定义的依旧是 sockaddr_in 结构体;传参时,需要将定义的 sockaddr_in 结构体变量的地址类型强转为 sockaddr*

相关文章:

【Linux 25】网络套接字 socket 概念

文章目录 &#x1f308; 一、IP 地址概念⭐ 1. IP 地址的作用⭐ 2. 源 IP 地址和目的 IP 地址 &#x1f308; 二、端口号概念⭐ 1. 源端口号和目的端口号⭐ 2. 端口号范围划分⭐ 3. 端口号 VS 进程 ID⭐ 4. 套接字 socket 的概念 &#x1f308; 三、传输层的典型代表协议⭐ 1. …...

python openai 通过Function Call 创建自动化任务

目录 一、什么是Function Call(函数掉用) 1. 功能概述 2. 工作原理 二、如何实现函数调用 1、定义自己的get_weather 函数 2、给助手添加函数调用 3、写好instrction,指导assistant去掉用你定义的方法。 4、最后也是最重要的,捕获 Assistant 的 Function Call 三、…...

设计模式之责任链的通用实践思考

责任链模式通常一般用在方法的拦截、监控、统计方面&#xff0c;比较典型的就是Spring的AOP拦截。 但写一些小的基础能力框架的时候&#xff0c;用AOP比较中&#xff0c;所以一般都是自己针对特定的功能写一些定制的责任链工具类&#xff0c;不太喜欢总是做一些定制化的东西&am…...

前端用canvas绘图并支持下载

1.根据数据绘制饼图 /** 绘制环形图 */ const drawPieCharts () > {const {canWithdrawalPriceFront,noWithdrawalPriceFront,haveWithdrawalPriceFront,} this.state;const myCanvas this.cavasRef.current;// ts-ignoreconst ctx myCanvas.getContext(2d);if (ctx) {…...

【Mac】Homebrew

1、Homebrew 简介 官网地址&#xff1a;https://brew.sh Homebrew 是一款Mac OS平台下的软件包管理工具&#xff0c;拥有安装、卸载、更新、查看、搜索等很多实用的功能。 Homebrew 主要有四个部分组成: brew、homebrew-core 、homebrew-bottles、homebrew-cask。 源说明br…...

Python笔记之线程库threading

Python笔记之线程库threading 参考博文 Python多线程笔记——简单函数版和类实现版 code review! Python 的 threading 库用于在程序中创建和管理线程。线程允许程序并发执行多个任务。以下是 threading 库的详解和一些简洁示例。 基本概念 线程&#xff1a;在一个进程中&a…...

go 包管理

Go语言所依赖的所有的第三方库都放在GOPATH目录下面 gomodule是Go语言默认的依赖管理工具 Modules是相关Go包的集合&#xff0c;是源代码交换和版本控制的单元&#xff0c;用于指定使用哪些源文件 GO111MODULEoff禁用gomodule&#xff0c;编译时从GOPATH和vendor文件夹中查找包…...

Js内建对象

数组解构 const arr ["1","2","3"]let a,b,c// 解构赋值 //将数组的第一个元素赋值给第一个变量&#xff0c;第二个元素赋值给第二个变量&#xff0c;依次类推[a,b,c] arr console.log(a,b,c) // 1 2 3 // 声明变量同时解构 let [a,b,c] [&qu…...

AXI接口的实现逻辑和底层原理,在FPGA中如何实现AXI接口,一篇文章足以搞明白!!!

AXI&#xff08;Advanced eXtensible Interface&#xff09;接口是一个点对点的接口&#xff0c;用于连接高性能的片上系统&#xff08;SoC&#xff09;中的处理器、外围设备、内存和其他IP核。以下是对AXI接口的详细解析&#xff0c;包括FPGA实现的原理、逻辑、速度以及详细的…...

《GBDT 算法的原理推导》 11-12计算损失函数的负梯度 公式解析

本文是将文章《GBDT 算法的原理推导》中的公式单独拿出来做一个详细的解析&#xff0c;便于初学者更好的理解。 公式(11-12)是GBDT算法中非常关键的一步&#xff0c;它表示了如何通过计算损失函数的负梯度来指导下一棵树的生长。 公式(11-12)如下&#xff1a; r m i − [ ∂ …...

mysql设计

大家好&#xff0c;我是捡田螺的小男孩。 昨天一位粉丝&#xff0c;咨询了一个并发的问题~ 我提供了一个乐观锁兜底的方案&#xff0c;然后发现他们的表&#xff0c;都没有加version字段的,我想到&#xff0c;这不是表设计通用字段嘛。因此&#xff0c;本文跟大家聊聊&#xf…...

Android 斗鱼面经

Android 斗鱼面经 文章目录 Android 斗鱼面经一面二面 一面 先简单描述一下JVM JRE JDK的关系 :::info JVM&#xff08;Java Virtual Machine&#xff09; Java 虚拟机。它只认识 xxx.class 这种类型的文件&#xff0c;它能够将 class 文件中的字节码指令进行识别并调用操作…...

【机器学习】26. 聚类评估方法

聚类评估方法 1. Unsupervised Measure1.1. Method 1: measure cohesion and separationSilhouette coefficient Method 2&#xff1a;Correlation between two similarity matricesMethod 3&#xff1a;Visual Inspection of similarity matrix 2. Supervised measures3. 决定…...

linux 最多能创建多少个 TCP 连接?

linux 最大允许TCP连接数 约束一&#xff1a;服务器的端口范围约束二&#xff0c;服务器文件描述符限制约束三&#xff1a;系统线程约束四&#xff1a;系统内存总结 tcp连接四元组&#xff1a;源ip&#xff0c;源端口 <> 目标ip&#xff0c;目标端口 连续对同一个目标ip及…...

我为何要用wordpress搭建一个自己的独立博客

我在csdn有一个博客&#xff0c;这个博客是之前学习编程时建立的。 博客有哪些好处呢&#xff1f; 1&#xff0c;可以写自己的遇到的问题和如何解决的步骤 2&#xff0c;心得体会&#xff0c;经验&#xff0c;和踩坑 3&#xff0c;可以转载别人的好的技术知识 4&#xff0c;宝贵…...

Linux系统每日定时备份mysql数据

一、创建存储脚本的文件夹 创建文件夹&#xff0c;我的脚本放在/root/dbback/mysql mkdir ... cd /root/dbback/mysql 二、编写脚本 vi backup_mysql.sh 复制脚本内容 DB_USER"填写用户名" DB_PASSWORD"填写密码" DB_NAME"数据库名称" # …...

书生大模型第一关Linux基础知识

任务一&#xff1a;完成SSH连接与端口映射并运行hello_world.py 1.SSH及其端口映射 2.在VSCode中安装插件&#xff1a; 3.创建开发机 最后点击创建&#xff0c;然后可能需要等待一段较长的时间&#xff0c;大概需要5分钟左右&#xff0c;如果需要排队则更长时间 然后选择…...

机器学习之fetch_olivetti_faces人脸识别--基于Python实现

fetch_olivetti_faces 数据集下载 fetch_olivetti_faceshttps://github.com/jikechao/olivettifaces sklearn.datasets.fetch_olivetti_faces(*, data_homeNone, shuffleFalse, random_state0, download_if_missingTrue, return_X_yFalse, n_retries3, delay1.0)[source] L…...

【系统设计】深入理解HTTP缓存机制:从Read-Through缓存到HTTP缓存的交互流程

在现代Web开发中&#xff0c;缓存机制扮演着至关重要的角色。它不仅提升了用户体验&#xff0c;还极大地优化了资源的使用效率。在这篇博文中&#xff0c;我们将从“Read-Through”缓存的概念出发&#xff0c;深入探讨HTTP缓存的工作原理和交互流程&#xff0c;并详细描述max-a…...

FLINK单机版安装部署入门-1

文章目录 FLINK单机版安装部署高于1.9.3需要修改配置文件flink-conf.yaml(低于1.9.3可以跳过)linux启动集群windows下启动Flink实例运行(单机)还有一种方式是上传任务包运行examples\streamingjava: Compilation failed: internal java compiler error高版本启动脚本 FLINK单机…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...