【网络】套接字socket编程预备知识

news2024/12/27 13:09:28

1.源IP地址和目的IP

计算机网络中的源地址和目的地址是用来标识网络中的不同主机的。

        源地址是指发送数据包的主机的地址,而目的地址则是指接收数据包的主机的地址,在数据包传输过程中,每经过一个路中器感交换机,都会根据目的地址讲行转发,直到到达目的主机。

        但是我们先来理解一下

        目标主机中存在很多进程,网络通信实际是不同主机中的进程在进行通信,并非主机与主机直接通信

 我们如果仅仅使用 IP 只能定位到目标主机,并且目标主机不是最终目的地,最终目的地是目标主机里的某个进程,数据包传到B主机的传输层的时候,上层的进程很多,就不知道该传给上层的哪个进程了。这个时候要想定位这个目标进程,需要依靠 端口号。

        抛开网络其他知识,将信息从主机 A 中的进程 A 发送至主机 B 中的 进程 B,这不就是 进程间通信 吗?之前学习的 进程间通信 是通过 匿名管道、命名管道、共享内存 等方式实现,而如今的 进程间通信 则是通过 网络传输 的方式实现

进程间通信的本质是让两个进程看到同一份资源,那么今天这个同一份资源就是网络。 

2.端口号(Port)

2.1.什么是端口号

        数据链路和IP中的地址,分别指的是MAC地址和IP地址。前者用来识别同一链路中不同的计算机,后者用来识别TCP/IP网络中互连的主机和路由器。

        在传输层中也有这种类似于地址的概念,那就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。

        传输层会解析这个端口号,然后将数据传向特定进程。

        端口号由其使用的传输层协议决定。因此,不同的传输协议可以使用相同的端口号。例如,TCP与UDP使用同一个端口号,但使用目的各不相同。这是因为端口号上的处理是根据每个传输协议的不同而进行的。

        数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块。如果是TCP则传给TCP模块、如果是UDP则传给UDP模块去做端口号的处理。即使是同一个端口号,由于传输协议是各自独立地进行处理,因此相互之间不会受到影响。

2.2.IP+端口号标识进程

两台主机进行网络通信,首先需要定位。

我们知道IP能标识一台主机,端口号Port能标识主机里特定进程,那么IP+Port就能标识唯一的一个进程!!!! 

实际上两台计算机通信其实是通过IP地址、端口号、协议号进行通信识别

我们可以一步一步去推断

  • 仅凭目标端口识别某一个通信是远远不够的。

        如图所示,①和②的通信是在两台计算机上进行的。它们的目标端口号相同,都是80。例如打开两个Web浏览器,同时访问两个服务器上不同的页面,就会在这个浏览器跟服务器之间产生类似前面的两个通信。在这种情况下也必须严格区分这两个通信。因此可以根据源端口号加以区分。

        上图中③跟①的目标端口号和源端口号完全相同,但是它们各自的源IP地址不同。此外,还有一种情况上图中并未列出,那就是IP地址和端口全都一样,只是协议号(表示上层是TCP或UDP的一种编号)不同。这种情况下,也会认为是两个不同的通信。

        因此,TCP/IP或UDP/IP通信中通常采用5个信息来识别(这个信息可以在Unix或Windows系统中通过netstat -n 命令显示。) 一个通信。它们是“源IP地址”、“目标IP地址”、“协议号”、“源端口号”、“目标端口号”。只要其中某一项不同,则被认为是其他通信。

也就是说,必须包含下面这些东西

网络传输中的必备信息组 [目的IP 源 IP || 目的 Port 源 Port]

  • 目的 IP需要把信息发送到哪一台主机
  • 源 IP信息从哪台主机中发出
  • 目的 Port将信息交给哪一个进程
  • 源 Port信息从哪一个进程中发出

这个就是套接字socket啊

2.3.端口号和PID的区别和关系

1.端口号 用于标识进程,进程 PID 也是用于标识进程,为什么在网络中,不直接使用进程 PID 呢?

  1. 进程 PID 隶属于操作系统中的进程管理,如果在网络中使用 PID,会导致网络标准中被迫中引入进程管理相关概念(进程管理与网络强耦合)
  2. 进程管理 属于 OS 内部中的功能,OS 可以有很多标准,但网络标准只能有一套,在网络中直接使用 PID 无法确保网络标准的统一性
  3. 并不是所有的进程都需要进行网络通信,如果端口号、PID 都使用同一个解决方案,无疑会影响网络管理的效率

所以综上所述,网络中的 端口号 需要通过一种全新的方式实现,也就是一个 2 字节的整数 port,进程 A 运行后,可以给它绑定 端口号 N,在进行网络通信时,根据 端口号 N 来确定信息是交给进程 A 的

  •  端口号与进程 PID 并不是同一个概念

进程 PID 就好比你的身份证号,端口号 相当于学号,这两个信息都可以标识唯一的你,但对于学校来说,使用学号更方便进行管理

  • 2.主机(操作系统)是如何根据 端口号 定位具体进程的?

这个实现起来比较简单,创建一张哈希表,维护 <端口号, 进程 PID> 之间的映射关系,当信息通过网络传输到目标主机时,操作系统可以根据其中的 [目的 Port],直接定位到具体的进程 PID,然后通过PID来对这个进程进行通信

        整个过程就是端口号->PID->进程

  • 3.我们怎么知道我们要通信的那个进程的目标端口号? 

这个端口号是公开的,所以一开始就能知道

  • 4. 一个进程可以绑定多个 端口号 吗?一个 端口号 可以被多个进程绑定吗?

        端口号 的作用是配合 IP 地址标识网络世界中进程的唯一性,如果一个进程绑定多个 端口号,依然可以保证唯一性(因为无论使用哪个 端口号,信息始终只会交给一个进程);但如果一个 端口号 被多个进程绑定了,在信息递达时,是无法分辨该信息的最终目的进程的,存在二义性

        所以一个进程可以绑定多个端口号,一个 端口号 不允许被多个进程绑定,如果被绑定了,可以通过 端口号 顺藤摸瓜,找到占用该 端口号 的进程

        如果某个端口号被使用了,其他进程再继续绑定是会报错的,提示 该端口已被占用

 3.认识传输层协议——TCP/UDP

传输层是用户层下面的第一层,我们使用网络通信时调用的接口基本就是这层的

主流的传输层协议有两个:TCP 和 UDP

两个协议各有优缺点,可以采用不同的协议,实现截然不同的网络程序,关于 TCP 和 UDP 的详细信息将会放到后面的博客中详谈,先来看看简单这两种协议的特点

TCP 协议:传输控制协议

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

字节流就像水龙头,用户可以根据自己的需求获取水流量

UDP 协议:用户数据协议

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

数据报则是相当于包裹,用户每次获取的都是一个或多个完整的包裹

关于 可靠性

  1. TCP 的可靠传输并不意味着它可以将数据百分百递达,而是说它在数据传输过程中,如果发生了传输失败的情况,它会通过自己独特的机制,重新发送数据,确保对端百分百能收到数据;
  2. 至于 UDP 就不一样,数据发出后,如果失败了,也不会进行重传,好在 UDP 面向数据报,并且没有很多复杂的机制,所以传输速度很快

总的来说TCP可靠性高,速度相对慢,UDP可靠性低,速度快。

        总结起来就是:TCP 用于对数据传输要求较高的领域,比如金融交易、网页请求、文件传输等,至于 UDP 可以用于短视频、直播、即时通讯等对传输速度要求较高的领域

        如果不知道该使用哪种协议,优先考虑 TCP,如果对传输速度又要求,可以选择 UDP

 4.网络字节序

4.1.高低位和高低地址

当我们了解了整数在内存中存储后,我们调试看⼀个细节:

#include <stdio.h>
int main()
{
 int a = 0x11223344;
 
 return 0;
}

 我们发现内存里存的怎么是44332211呢?

这个就和大小端有关系了

C语言中的大小端(Endianness)指的是字节顺序的不同方式,即如何将多字节的数据类型(如整数、浮点数)在内存中存储。

  • 数字的高低位

先来了解数字的高低位

0x12345678
高位     低位

越靠近1这边的位就叫高位,越靠近8那边的位叫低位

  • 高低地址

什么是高地址,什么是低地址,举举例说明?

可以把主存看成一本空白的作业本,你现在要在笔记本上记录一些内容,他的页码排序是

第一页 : 0x0000001
第二页 : 0x0000002
…
最后一页: 0x0000092

下面有两种使用情况

        第一种:如果你选择从前向后记录(用完第一页,用第二页,类推)这就是先使用低地址,后使用高地址.

0x0000001 -> 0x0000002-> … -> 0x0000092

业内有这样表述:动态内存分配时堆空间向高地址增长,说的就是这种情况.
这个向高地址增长就是先使用低地址,后使用高地址的意思.

        第二种:如果你选择从后往前记录(先用笔记本的最后一页,用完后使用倒数第二页,类推) 这就是先使用高地址,后使用低地址

0x0000092 -> … ->0x0000002 -> 0x0000001

业内表述:0xbfac 5000-0xbfad a000是栈空间,其中高地址的部分保存着进程的环境变量和命令行参数,低地址的部分保存函数栈帧,栈空间是向低地址增长的.

这个向低地址增长就是先使用高地址,后使用低地址的意思.

高地址低地址容易与高位低位产生混淆.

我们从小就知道,数字是从左往右读的,这符合人类的普遍阅读习惯。
        比如十进制数 65535,数位从高到低依次是万,千,百,十,个。对十进制数而言,最左边是高位数位,最右边是低位数位

        我们类比到16进制数 0x12345678,也从左往右来阅读这个数。那么,对十六进制数而言,最左边就是高位字节,最右边是低位字节

4.2.大小端字序

首先,你可能需要对内存有一些基本的认识:

  1. 一个内存单元可以存储一个字节的内容,因此内存单元也常常被称为字节单元。
  2. 一个内存单元可以存储8个比特,即8个二进制数。但是,如果换算成16进制,一个内存单元仅能容纳2个16进制数。

如图所示,我们在画内存示意图的时候,我们用一个绿色矩形表示一个内存单元,每一个内存单元都有一个内存地址,方便计算机的处理器找到这块内存单元。
        另外,我们也习惯于内存地址将低地址端放在下面,高地址端放在上面。

 这个习惯,我猜测可能与古人建房子的习惯类似,所谓“万丈高楼平地起”,最先建的总是低层,然后再建高层。高层究竟建多高,这个总是不断发展和变化的,但是最底层总是从零开始,这个是相对稳定的。

还是以十六进制数 0x12345678 为例,当它以大端字节序存储在内存中时,低地址端 0x0000 存储该数的高位字节 0x12;高地址端 0x0003 存储的是该数的低位字节 0x78。 

 

当 0x12345678 以小端字节序存储在内存中时,低地址端 0x0000 存储该数的低位字节 0x78;高地址端 0x0003 存储的是该数的高位字节 0x12

4.3.从网络传输看待字节序

        在网络出现之前,使用大端或小端存储都没有问题,网络出现之后,就需要考虑使用同一种存储方案了,因为网络通信时,两台主机存储方案可能不同,会出现无法解读对方数据的问题。

  所以在TCP/IP协议规定了在网络上必须采用网络字节顺序,也就是大端模式

  • 对于char型数据只占一个字节,无所谓大端和小端。
  • 而对于非char类型数据,必须在数据发送到网络上之前将其转换成大端模式。

接收网络数据时按符合接受主机的环境接收。

简而言之,网络字节序是大端字节序。

        发送数据时,将 主机字节序 转化为 网络字节序,接收到数据后,再转回 主机字节序 就好了,完美解决不同机器中的大小端差异,可以用下面这批库函数进行转换,在发送/接收时,调用库函数进行转换即可

#include <arpa/inet.h>

// 主机字节序转网络字节序
uint32_t htonl(uint32_t hostlong); // l 表示32位长整数
uint32_t htons(uint32_t hostshort); // s 表示16位短整数

// 网络字节序转主机字节序
uint32_t ntohl(uint32_t netlong); // l 表示32位长整数
uint32_t ntohs(uint32_t netshort); // s 表示16位短整数

我们通常编写和阅读的电脑文件中,总是习惯于从上到下,从左到右。此时低地址在左边或者在上边,高地址在右边或者下边。

十进制数 40190 等于十六进制数 0x9cfe,十进制数 5222 等于十六进制数 0x1466。

我们聚焦抓包的内容的第 4 行,即起始地址为 0x0040,最后一个地址为 0x004f

  • 0x9cfe 的高位字节 0x9c 保存在低地址端 0x0045,低位字节是 0xfe 保存在高地址端 0x0046
  • 0x1466 的高位字节 0x14 保存在低地址端 0x0047,低位字节是 0x66 保存在高地址端 0x0048

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

乒乓球AI机器人赢了人类!正反手灵活转换,擦网球高球都能接,专业教练:达到中级选手水平

巴黎奥运会乒乓球团体赛如火如荼&#xff0c;谷歌机器人申请出战—— 首个达到人类竞技水平的机器人Agent发布&#xff01; 你看一个没留神&#xff0c;就赢了专业教练一个球&#xff01; 正反手快速转换&#xff0c;连续进攻也是不在话下~ 面对一些突发战术&#xff0c;比如…

在线办公小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;通知公告管理&#xff0c;员工管理&#xff0c;部门信息管理&#xff0c;职位信息管理&#xff0c;会议记录管理&#xff0c;待办事项管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首…

Swagger的介绍与使用(二)

一. 介绍( Spring Boot JDK 17 Swagger 3&#xff08;OpenAPI&#xff09;结合使用) 根据2024年当前环境来看&#xff0c; Spring Boot JDK 17 Swagger 3&#xff08;OpenAPI&#xff09;结合使用更加有趋势 将Spring Boot、JDK 17和Swagger 3&#xff08;OpenAPI&#xff…

xxl-job适配达梦数据库

参考资料&#xff1a; 【达梦数据库】从 Mysql 迁移到 DM8_从 mysql 移植到 dm Xxl-job适配达梦数据库 Xxl-job适配达梦数据库 按照这篇文章修改所有Mapper.xml文件&#xff0c;但是运行会报错。 按照下面的文章修改 XxlJobLogMapper.xml 如何将 XxlJob 集成达梦数据库_xx…

矩阵转置(c语言)

1.KiKi有一个矩阵&#xff0c;他想知道转置后的矩阵&#xff08;将矩阵的行列互换得到的新矩阵称为转置矩阵&#xff09;&#xff0c;请编程帮他解答。 //输入描述&#xff1a; //第一行包含两个整数n和m&#xff0c;表示一个矩阵包含n行m列&#xff0c;用空格分隔。(1≤n≤10…

SQLite 数据库安装及使用(Linux)

目录 引言 SQLite 的特点 SQLite 的应用场景 SQLite数据库的安装 方法一&#xff1a;使用包管理器安装 方法二&#xff1a; 从源码编码安装 SQLite数据库的基础命令 1.系统命令 2.SQL命令 sqlite编程接口 引言 SQLite 是一种轻量级的数据库管理系统&#xff0c;它不…

uniapp项目-购物商城【无接口,下载改appid即可使用】

&#x1f939;‍♀️潜意识起点&#xff1a;个人主页 &#x1f399;座右铭&#xff1a;得之坦然&#xff0c;失之淡然。 &#x1f48e;擅长领域&#xff1a;大前端 是的&#xff0c;我需要您的&#xff1a; &#x1f9e1;点赞❤️关注&#x1f499;收藏&#x1f49b; 是我…

零样本学习——从多语言语料库数据中对未学习语言进行语音识别的创新技术

引言 在全球众多的语言中&#xff0c;只有极少数的语言在语音识别领域取得了显著的进展。这种不平衡现象的主要原因是&#xff0c;现有的语音识别模型往往依赖于大量的标注语音数据&#xff0c;而这些数据对于许多语言来说难以获得。 近年来&#xff0c;尽管语音识别技术取得…

6.3 第三方库的安装与使用

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

英镑与日元:货币市场的双重挑战

一、英镑的波动与策略 近期&#xff0c;英镑兑所有主要货币出现大幅下挫&#xff0c;尤其是在7月&#xff0c;英镑成为投机市场最大的净多头仓位。然而&#xff0c;上周英镑抹去了第二季的大部分涨幅&#xff0c;主要受到英国央行对利率前景的鸽派重新定价的影响&#xff0c;以…

【生信入门】预览快速体验Linux-重生之小明闯Linux

生信少走弯路,快试试生信云专用服务器。新用户注册免费体验5小时。https://www.tebteb.cc 一.故事 小明的Linux冒险 在一片混沌的黑暗中&#xff0c;小明睁开了眼睛。他感到头痛欲裂&#xff0c;四周一片漆黑&#xff0c;只有一行闪烁的字符映入眼帘&#xff1a; [xiaomingu…

如何实现Redis和Mysql中数据双写一致性

在我们的实际开发中&#xff0c;我们用到了redis缓存一些常用的数据&#xff08;如热点数据&#xff09;用来提高系统的吞吐量。 但是不可以避免的出现了数据的修改场景&#xff0c;这就导致了数据库中的数据和Redis中出现不一致性的情况。如何保证数据一致性就显得非常重要了&…

H3C智能管理中心byod/index.xhtml接口存在远程命令执行漏洞

@[toc] H3C智能管理中心byod/index.xhtml接口存在远程命令执行漏洞 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学…

C++基础编程的学习3

nullptr关键字 在C11之前&#xff0c;空指针通常用NULL或0表示。然而&#xff0c;这些表示方法存在类型安全问题。C11引入了nullptr关键字&#xff0c;它提供了一个明确的、类型安全的空指针值。 Lambda表达式 Lambda表达式是C11引入的一种便捷的匿名函数定义方式。当Lambda…

海量数据处理商用短链接生成器平台 - 12

第三十五章 微信支付Native订单API测试实战和签名流程解读 第1集 微信支付-快速验证参数配置方法和统一下单接口开发 简介&#xff1a;微信支付-快速验证参数配置方法和统一下单接口开发 接口文档 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml 编码实…

03_Electron 主进程和渲染进程、点击(拖放)打开文件功能

Electron 主进程和渲染进程 一、Electron 主进程和渲染进程二、Electron 主进程和渲染进程中使用 Nodejs 以及 Nodejs 第三方模块2.1、主进程中使用 Nodejs 模块2.2、渲染进程中 使用 Nodejs 模块2.3、BrowserWindow 中通过 preload加载的js 文件可以直接使用nodejs 模块2.4、渲…

大小仅为Rust四分之一!MoonBit 现已支持Wasm组件模型

使用 MoonBit 开发 Wasm 组件模型 Wasm组件 WebAssembly&#xff08;Wasm&#xff09;是一种新的低级虚拟指令集标准&#xff08;low-level virtual instruction set standard&#xff09;&#xff0c;用于沙箱模型。低级的&#xff0c;意味着它接近原生速度。虚拟的&#xff…

全网最最最全的LVS详解!!!

1 LVS-集群和分布式 1.1 集群 LVS&#xff08;Linux Virtual Server&#xff09;集群&#xff0c;即Linux虚拟服务器集群&#xff0c;是一个在Unix/Linux平台下实现负载均衡集群功能的系统。它由国人章文嵩博士在1998年开发&#xff0c;是中国国内最早出现的自由软件项目之一…

yolov8 剪枝 - DepGraph

2024年8月5 5000张图片&#xff0c;2个类别。 yolov8n 初始&#xff1a; 185 layers, 3151904 parameters, 31936 gradients, 8.7 GFLOPs 经过三次finetune后&#xff1a; 185 layers, 2327024 parameters, 31936 gradients, 6.6 GFLOPs 经过第四次fintune后&#xff1a; …

“write()” 与 “ tcp缓冲区 ” 之间的关系

write&#xff08;&#xff09;写入tcp缓冲区过程 write&#xff08;&#xff09;将该文本写入到tcp缓冲区中本质是数据的拷贝&#xff0c;当write()调用完&#xff0c;数据不一定发给tcp发送缓冲区中 因为&#xff1a; 有没有拷贝成功&#xff0c;都不由write&#xff08;&a…