【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*

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/906399.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

配置mysql 主主模式 GTID

文章目录 一、前提二、修改my.cnf主1 10.255.131.9主2 10.255.131.10 三、配置主主3.1 配置主 10.255.131.93.2 配置从 10.255.131.103.3 配置主 10.255.131.103.4 配置从 10.255.131.9 四、验证五、同步问题排查以及恢复5.1 查看同步状态5.2 查看同步是否数据一致性&#xff0…

自动化研磨领域的革新者:半自动与自动自磨机的技术突破

据QYResearch调研团队最新报告“全球半自动和自动自磨机市场报告2023-2029”显示&#xff0c;预计2029年全球半自动和自动自磨机市场规模将达到5.3亿美元&#xff0c;未来几年年复合增长率CAGR为3.5%。 图00001. 半自动和自动自磨机&#xff0c;全球市场总体规模 如上图表/数据…

最长方连续方波信号

更多关于刷题的内容欢迎订阅我的专栏华为刷题笔记 该专栏题目包含两部分&#xff1a; 100 分值部分题目 200 分值部分题目 所有题目都会陆续更新&#xff0c;订阅防丢失 题目描述 输入一串方波信号&#xff0c;求取最长的完全连续交替方波信号&#xff0c;并将其输出&#x…

ARB链挖矿DApp系统开发模式定制

在区块链生态中&#xff0c;挖矿作为一种获取加密资产的方式&#xff0c;越来越受到关注。ARB链凭借其高效的性能和灵活的智能合约系统&#xff0c;成为了开发挖矿DApp的理想平台。本文将探讨ARB链挖矿DApp的开发模式定制&#xff0c;包括架构设计、功能实现以及最佳实践。 ARB…

YoloV8改进策略:Block改进|RFE模块,提高小物体的识别精度|即插即用|代码+修改过程

摘要 论文介绍 本文介绍了一种基于YOLOv5的人脸检测方法,命名为YOLO-FaceV2。该方法旨在解决人脸检测中的尺度变化、简单与困难样本不平衡以及人脸遮挡等问题。通过引入一系列创新模块和损失函数,YOLO-FaceV2在WiderFace数据集上取得了优异的表现,特别是在小物体、遮挡和困…

使用 Elasticsearch 进行语义搜索

Elasticsearch 是一款功能强大的开源搜索引擎&#xff0c;可用于全文搜索、分析和数据可视化。传统上&#xff0c;Elasticsearch 以其执行基于关键字/词汇的搜索的能力而闻名&#xff0c;其中文档基于精确或部分关键字匹配进行匹配。然而&#xff0c;Elasticsearch 已经发展到支…

计算机网络:网络层 —— 虚拟专用网 VPN

文章目录 虚拟专用网 VPN 概述内联网 VPN外联网 VPN 虚拟专用网 VPN 概述 虚拟专用网&#xff08;Virtual Private Network&#xff0c;VPN&#xff09;&#xff1a;利用公用的因特网作为本机构各专用网之间的通信载体&#xff0c;这样形成的网络又称为虚拟专用网。 出于安全…

C语言函数嵌套调用

函数嵌套调用就是在一个函数中调用另一个函数&#xff1b; 看一个例子&#xff1b; max2函数返回2个整数中大的一个&#xff1b;max4中调用max2&#xff0c;实现返回4个整数中最大的一个&#xff1b; int max2(int, int); int max4(int, int, int, int);......void CCjjyyV…

C++:继承及其相关问题

继承的定义 继承机制是⾯向对象程序设计实现代码复⽤的重要⼿段&#xff0c;它允许我们在保持原有类特性的基础上进⾏扩展&#xff0c;增加⽅法 (成员函数) 和属性 (成员变量)&#xff0c;从而产⽣的类&#xff0c;这样的类称为派⽣类&#xff0c;也称为子类。而这样的类就成为…

Centos7.9 x86架构部署

一、部署环境 表 1‑1 环境服务版本号系统centos7.9_2009运行环境1JDK1.8_321前端WEBNginx1.14数据库postgresqlpostgresql13postgis3.1pgrouting3.1消息队列rabbitmq3.8.16运行环境2erlang23.3.3.1 二、部署JDK 2.1下载JDK安装包 官网下载JDK8 官网地址&#xff1a; https…

【uniapp3】分享一个自己写的h5日历组件

简言 分享一下自己基于uniapp写的日历组件。如果不太满足你的需求&#xff0c;可以自己改造。 日历 实现分析&#xff1a; 页面显示 - 分为顶部显示和日历显示&#xff0c;我这里做了多行和单行显示两种情况&#xff0c;主要是当时看着手机的日历做的&#xff0c;手机上的…

Nginx安装配置详解

Nginx Nginx官网 Tengine翻译的Nginx中文文档 轻量级的Web服务器&#xff0c;主要有反向代理、负载均衡的功能。 能够支撑5万的并发量&#xff0c;运行时内存和CPU占用低&#xff0c;配置简单&#xff0c;运行稳定。 写在前 uWSGI与Nginx的关系 1. 安装 Windows 官网 Stabl…

Java版企电子招标采购系统源业码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

MS01SF1 精准测距UWB模组助力露天采矿中的人车定位安全和作业效率提升

在当今矿业行业&#xff0c;随着全球对资源需求的不断增加和开采难度的逐步提升&#xff0c;传统的作业方式面临着越来越多的挑战。露天矿山开采&#xff0c;因其大规模的作业环境和复杂的地形特点&#xff0c;面临着作业人员的安全风险、设备调度的高难度以及资源利用率低下等…

【Web.路由】——路由模板

路由模板负责根据规则生成URL&#xff0c;从而使得请求可以正常访问到资源。 总之就是——》》》 规范如何写一个url&#xff0c;并且命名以方便进行管理。 在Asp.net core中的Http管道机制&#xff0c;UseRouting()和 UseEndpoints()这两个中间件来实现整个路由系统。关于asp…

c加加11第二弹~

1lambda 1.1.lambda表达式书写格式 [capture-list] (parameters) mutable -> return-type { statement} 1.2lambda表达式各部分说明 [capture-list] : 捕捉列表&#xff0c;该列表总是出现在lambda函数的开始位置&#xff0c;编译器根据[]来判断接下来的代码是否为lamb…

记录|多线程和异步简单理解

目录 前言一、单线程二、多线程-Thread多线程是都多少个的时候会导致性能变差 三、多线程-Task类Task的优势 四、异步- awaitawait注意&#xff1a;多个Task Run()天剑await后&#xff0c;变成了同步执行解决方法 更新时间 前言 参考视频&#xff1a;C#基础教程 多线程编程入门…

凸极式发电机的相量图分析和计算,内功率因数角和外功率因数角和功角的定义。

图1&#xff1a;同步发电机稳态相量图 若发电机为凸极式&#xff0c;由于凸极机正、交轴同步电抗不等&#xff0c;即xd≠xq&#xff0c;因此必须先借助虚构电动势 E ˙ Q E ˙ q − ( x d − x q ) I ˙ d \dot{E}_Q\dot{E}_q-(x_d-x_q)\dot{I}_d E˙Q​E˙q​−(xd​−xq​)…

C语言原码、反码和补码的详解

C语言原码、反码和补码的详解 放在最前面的1、前言正数的原码、反码和补码负数的原码、反码和补码 2、整数的原码&#xff08;2.1&#xff09;原码的定义&#xff08;2.2&#xff09;计算原码 3、整数的反码&#xff08;3.1&#xff09;反码的定义&#xff08;3.2&#xff09;计…

idea 导入Spring源码遇到的坑并解决

1.下载相关文件 通过百度网盘分享的文件&#xff1a;Spring 链接&#xff1a;https://pan.baidu.com/s/1r9rkGOCaY9SFn9ecng5cIg?pwd8888 提取码&#xff1a;8888 2.配置gradle环境 gradle下载地址 需要翻墙下 https://services.gradle.org/distributions/ 我选择的是 grad…