学习网络编程No.3【socket理论实战】

news2024/11/24 6:38:19

引言:

北京时间:2023/8/12/15:32,自前天晚上更新完文章,看了一下鹅厂新出的《扫毒3》摆烂至现在,不知道是长大了,还是近年港片就那样,给我的感觉不是很好,也可能是国内市场对港片不大友好,反正质量不怎么高。然后昨天大部分时间花在了追《我欲封天》这本小说,主要是情节比较耐人寻味,另人欲罢不能!耳根不愧是经典的代名词。再后来到了晚上刷了会视屏,先是看了《饥饿站台》的剪辑,然后又看了一下《饥饿游戏》的剪辑,这种视屏真的是划不走,也是令人欲罢不能,哎!然后刚午睡醒来,为了今天能够更文,现在必须要豁出去了,虽然娱乐了挺久,但是没有关系,就当是对前几天疯狂码字的奖励吧!今天就让我们重拾键盘来一个疯狂星期六吧!该篇博客让我们来学习一下有关套接字(socket)的相关知识吧!

在这里插入图片描述

深入学习网络传输基本流程

在上篇博客中,我们重点对网络协议栈中的网络层和数据链路层进行了详解,明白了为什么说路由器和交换机工作于网络层和数据链路层,并且对于IP地址和MAC地址以及数据传输有了一定的认识,所以此时我们再来谈谈相关知识。

回顾封装、解包和分用
在上篇博客中,我们重点讲解了有关网络传输的基本流程,明白当一个数据想要从主机A发送到主机B,因为网络协议栈每一层都有与其对应的协议和需要实现的功能,所以我们需要在数据经过网络协议栈时,将每一层特定的协议封装到数据中,其中就包括报头协议、识别协议和功能协议,所以只有对每一层特定的协议进行了封装,最后在数据向下传递或者向上传递时,才能正确的按照顺序传到每一层协议,并且正确的被每一层协议识别,然后完成在该层协议中对应需要实现的功能,当然这也就是解包和分用的概念,并且注意,当数据在传输层时我们称为报文,在网络层称为数据报,在数据链路层称为数据包,在物理层则称为数据帧。

深入理解MAC地址和IP地址
在上篇博客有关数据链路层和网络层中,我们简单理解了一下MAC地址和IP地址,明白MAC地址是当数据在局域网中传输,交换机对于某网卡的唯一标识符,而IP地址是对于广域网中进行数据传输,路由器对于某主机的唯一标识符。并且明白,因为主机的IP地址是通过路由器向网络中的DHCP协议申请,所以对应路由器的路由表中天生就记录了该主机的IP地址,也就是在广域网中当某个其它主机想要发送数据给目标主机时,只要让与其对应的路由器根据路由表中对应其它路由器的IP地址找到目标路由器就等于是找到了目标主机,当找到目标路由器并且将数据发送之后,注意:虽然目标路由器的路由表中就有对应主机的IP地址,但是IP地址只是起一种标识作用,并不能直接接收数据(只有网卡,也就是MAC地址才具有接收数据的功能),所以此时最关键的问题就是要让路由器获取到目标主机的MAC地址,那么问题就来了路由器如何获取到目标主机的MAC地址呢?首先明白,此时需要分为两种情况,一种是路由器与目标主机之间存在直接联系,另一种是目标主机和路由器之间不存在直接联系,什么意思呢?也就是需要判断该主机是否在路由器的子网中(类比学校主机和自己的笔记本电脑),当我们的笔记本电脑使用WIFI时,此时就表示该主机与路由器之间存在联系,反之学校机房的电脑与路由器不存在联系(是否获取到路由器本身提供的IP地址接口)。情况一:也就是存在联系,那么路由器和目标主机之间就可以直接通过路由器提供的IP地址接口进行交互(同理目标主机获取自己的IP地址),直接将自己的MAC地址告诉路由器,最后路由器直接根据自己的转发表和交互接口将需要传送的数据全部传给目标主机。情况二:反之,路由器和目标主机之间不存在联系,那么此时同理路由器需要先将数据交给交换机,然后通过交换机传送给目标主机,但是,此时同理有一个问题,也就是路由器如何找到交换机呢?同理路由器需要根据自己转发表中目标主机的MAC地址和交换机之间的关系来确定将数据传送给那一个交换机,也就是同理此时路由器需要获取到目标主机的MAC地址,问题也就来了,在路由器和目标主机不存在直接关系的情况下,路由器如何获取到MAC地址?答案是:此时涉及到一个叫ARP的网络协议,很好理解,也就是当某路由器获取到了目标主机的IP地址后,根据ARP网络协议,此时路由器会进行ARP广播,也就是将目标主机的IP地址通过交换机发送给所有与交换机连接的主机,当目标主机发现自己的IP地址与接收到的IP地址相同时,此时目标主机就会进行ARP响应操作,也就是将自己的MAC地址发送给路由器,此时路由器就成功的获取到了目标主机的MAC地址,这也就是ARP网络协议。当我们通过该方法让路由器获取到了目标主机的MAC地址,本质也就是让IP地址的标识作用变得更加实质性(IP地址->MAC地址)之后,此时路由器就可以根据转发表中MAC地址与交换机之间的关系,找到与目标主机关联的目标交换机,从而实现将数据从路由器交给交换机再给网卡。注意:虽然此时路由器也获取到了MAC地址,但是因为路由器和目标主机之间并不存在关系,所以不能直接传送数据,必须经过交换机,与上述情况一有一定区别。明白了这些之后,此时我们对MAC地址和IP地址以及数据传输过程中的细节知识就有了更深的理解,下面我们一起看副图来具体理解一下广域网中(IP地址)数据的传输过程(结合封装和分用理解),如下图所示:
在这里插入图片描述
如上图所示,与局域网中的数据传输过程不同,此时在广域网中IP地址是必不可少的部分,结合之前有关封装、解包和分用的知识以及数据链路层的知识,此时我们就可以更加深入的理解为什么数据链路层可以支持多种不同的协议,本质如上图就是因为在数据传输的过程中,每一层协议想要被识别就需要有对应的报头,当我们在发送数据时,在数据链路层是根据以太网协议来封装数据包,那么交换机想要再将数据传送给路由器,那么前提就是它根据以太网协议完成了以太网协议的解包过程,解包完成之后再根据协议进行分用,此时就可以成功的将数据包传送给路由器,此时路由器再经过一些列的查询路由表过程,找到含有目标IP地址的路由器,最后同理当我们想要将数据从路由器传送给目标交换机时,此时就一定需要对目标交换机使用的协议进行封装(以太网协议、令牌环协议、无线LAN协议),只有这样才能使交换机正常工作,所以依据这一原理(封装、分用、解包)就可以很好的解决数据链路层协议不一致问题,当然为什么不一致在上篇博客谈TCP/IP协议栈时,我们有重点强调。所以这也就是为什么网络层和传输层的IP协议以及TCP协议保持一致时,数据链路层可以不保持一致的原因。

注意: 明白上述知识,再加上上述对IP地址和MAC地址的深入理解,此时我们再明白最后一点之后,就可以说是无敌的存在了,也就是为什么说源IP地址和目标IP地址不变,而MAC地址在变,搞明白这个点,就会有一种守得云开见月明的感觉,在上述我们明白了一个很重要的概念:也就是IP地址就是一种标识,MAC地址才是实质性的,原因就在于MAC地址代表的是网卡,只有网卡才具有传输和接收数据的能力,也就是说在广域网中,路由器查询路由表寻找目标IP的过程本质是一个寻找MAC地址的过程,也就是当一个路由器想要将数据传输给下一个路由器(简称:下一跳),这个过程同理我们上述所说路由器如何获取MAC地址,也就是路由器无论是否找到目标路由器,它想要完成下一跳,在第一次时,它一定需要进行一次ARP广播(同理上述所说),然后某个路由器发现它的路由表中存在目标IP地址,那么它就进行ARP响应,将自己的MAC地址发送给对应路由器,最终同理路由器获取到了目标路由器的MAC地址,然后根据该目标MAC地址将数据传送给目标路由器(并且记录IP地址和MAC地址间的映射关系,记录之后下一次传输时,就可以直接找到MAC地址,也就是不需要再进行ARP广播),接下来的过程统统同理。明白这点之后,小小的数据传输过程如砍瓜切菜一般,概念我们就彻底搞定。如下图所示,就是我们云服务器上的IP地址和MAC地址:

在这里插入图片描述

什么是套接字(socket)

明白了上述知识,此时我们正式来看一看该篇博客的主题,有关套接字相关的知识,莫慌,我一直强调,想要理解一个陌生的东西,最好的方式就是类比学过的知识,首先明白套接字是在网络协议栈中传输层使用TCP/UDP协议实现的一种网络通信方式,也就是操作系统在传输层提供了一套接口(套接字)供给我们使用,让我们可以实现网络通信(系统调用)。然后因为网络通信的本质是进程间通信,所以套接字和消息队列、共享内存、管道一样,都是一种进程间通信方式,只不过前者不仅可以在系统内部实现进程间通信(本地套接字),也可以实现网络通信(网络套接字),而后者只能用于进程间通信,当然具体为什么网络通信的本质是进程间通信,下述我们详解讲解。

从网络数据传输看套接字
对于上述套接字的关键概念有了一定理解之后,此时我们从套接字是一种网络通信,而网络通信是一种进程间通信来深入理解一下有关套接字的知识。首先,此时我们对网络数据传输过程已经如火纯情,对于数据从主机A到主机B的过程了如指掌,那么明白数据从A到B不是我们的目的,我们的目的是让主机B在接收到数据之后可以去访问某种服务,然后将对应的服务返回给主机A,并且根据网络协议栈的知识,我们知道这个申请服务和访问服务的过程一定是在应用层实现,所以此时就有了客户端和服务端(服务器)的概念,也就是两个主机之间的网络间通信本质就是客户端(APP)和服务端(该APP的功能实现)之间的通信,明白了这点之后,此时对于网络通信就是进程间通信的概念可以说是更加明了了,但还不够,我们还可以知道,当我们需要通过某个客户端(APP)去获取某个功能时,这个操作是随时随地都能完成的,这也就说明我们访问的服务一定是被启动,并且一直处于运行状态的,所以明白了这两点,我们就可以把客户端和服务端理解成两个进程,当我们访问某个客户端(APP)就是在启动某个进程,而服务端进程是一个被启动的死循环进程。总而言之:网络通信就是进程间通信。

深入理解网络通信
明白了上述知识,对于套接字就是一种网络间通信,一种进程间通信的概念我们已然耳聪目明,呼之欲出,此时对于数据从主机A到主机B的过程我们就可以深入理解为主机A创建一个进程(应用层打开APP),然后该进程执行相应的代码(创建套接字等),再根据TCP/UDP协议以及套接字(与主机B建立联系),此时数据就被传送到主机B,然后主机B经过物理层、数据链路层、网络层到达传输层,在传输层上套接字就可以将对应的数据推送给上层指定的进程。

此时对于上述这段话我们还不能很好理解,当然有关数据在网络层封装IP地址以及路由器、交换机相关的知识我们不再强调,此时我们需要搞定的问题是:套接字如何将数据推送给上层指定的进程以及套接字的本质是什么?第一个问题:也就是在系统中有那么多的进程,套接字如何找到目标进程呢?明白,同理IP地址,当某主机想要实现网络通信,那么前提就一定是它获取到了目标主机的IP以及目标进程的标识,因为网络通信的本质就是进程间通信,所以此时只要对某主机和某进程进行的标识,那么在整个互联网中,我们就能找到那个唯一的服务端进程,从而顺利完成两个进程间的通信。明白这点,端口号的概念油然而生,端口号就是用来标识那个网络中唯一的进程,所以对于使用源IP、源端口号、目标IP、目标端口号实现的进程间通信方式,我们就称为套接字(socket)网络通信。所以也就是套接字可以直接根据端口号找到目标进程,然后将对应数据拷贝到该进程的缓冲区中,注意:操作系统内部存在许多进程标识符(PID)用于管理进程,但是在网络通信中想要识别一个进程我们只使用端口号,这样可以降低进程管理模块和网络模块之间的耦合。

深入理解接收和发送数据
搞定了上述知识,此时我们对网络通信有了更深的认识,明白网络通信就是进程间通信,明白进程间通信需要使用目标IP和目标端口号来标识两个唯一的进程,明白socket通信方式,当然具体socket如何实现这种通信方式,下述和下一篇博客我们详谈,本质就是各种socket接口的使用,所以socket网络通信本质其实也叫socket编程接口。搞定这些之后,此时我们来看看有关网络通信的最后一个知识点,进程接收和发送数据的具体过程: 首先是接收,在之前我们将网络协议栈与操作系统结合那块知识我们谈到过网络协议栈是和文件系统有关的,这块知识充分体现,也就是目标进程启动时,用户可以在该进程中打开一个文件,文件被打开之后,根据文件系统的知识,此时操作系统就会为其创建struct file结构体,其中就包含了该文件的inode和缓冲区等信息,然后当目标进程对应的套接字接收到数据之后,此时该套接字就会根据TCP协议和有效载荷(数据)找到目标进程的端口号,然后该套接字根据目标进程对应打开文件的文件描述符找到被打开文件,最终将自己缓冲区中的数据拷贝到该文件缓冲区中。其次是发送:同理,创建进程(启动APP),在该进程中打开文件,将数据写入到该文件的缓冲区中,再经过操作系统将该缓冲区中的数据拷贝到与该进程对应的套接字缓冲区中,然后套接字经过网络协议栈将数据发送给目标主机。通过上述方式,进程就可以很好的实现如何凭借文件进行网络数据的接收和发送。

认识TCP协议和UDP协议

明白了上述有关socket网络通信的知识,此时我们来简单认识一下TCP和UDP协议,因为这两种协议都是传输层协议,且套接字(socket)就是工作在传输层,简而言之也就是我们可以利用不同的协议来实现socket网络通信,下述就是有关TCP和UDP之间的特点,也就是不同,如下所述:

1.TCP
TCP协议是一种传输层协议,也叫作传输控制协议,是一种面向连接、面向字节流的可靠性协议,怎么理解呢?面向连接也就是说在数据发送之前,发送方和接收方需要提前建立一个联系,而面向字节流指的是该协议对于数据的读取/发送没有控制,想读/发多少就读多少,而可靠性表示的是使用TCP协议该协议就会保证对应的数据被接收方接收,如果中途失败,那么TCP协议就会进行重传等操作,反正就是通过各种手段来确保数据传输成功(数据分段、流量控制、拥塞机制等)。

2.UDP
同理UDP协议也是一种传输层协议,也叫作用户数据报协议,是一种无连接、面向数据报等待不可靠协议,同理TCP理解,此时对于UDP的理解就比较简单,UDP协议在发送数据之前不需要建立发送方和接收方的联系,并且在读取/发送数据时必须完整的读取/发送,而不可靠性表示的也就是发送方将数据发送之后,不再关心接收方是否接收到数据。

总结来说:TCP适用于对数据传输可靠性要求较高的场景,而UDP适用于对实时性要求较高、对数据传输可靠性要求较低的场景。【想要进一步理解可参考该链接:深入学习TCP/UDP】

网络字节序

认识了TCP和UDP之后,此时我们对于socket编程就又进了一步,以后我们肯定会对TCP和UDP协议各自的特点进行区分,然后实现不同的socket网络通信,也就是TCP网络通信和UDP网络通信,不过在此之前我们需要理解一下网络字节序相关的知识,该知识本质是为了解决有关数据使用大端存储还是小端存储的问题,如下图所示:

在这里插入图片描述
如上图所示,此时我们明白,在计算机中进行多字节存储的时候,由于体系结构的原因,此时不仅支持大端存储,也支持小端存储,所以如果一台大端存储的机器和一台小端存储的机器之间进行网络通信,那么此时就会出现数据被反向存储的问题,最终影响数据正确性,所以为了解决该问题,此时就提出了网络字节序的概念,规定网络字节序列必须是大端,所以在网络中获取到的数据就一定是大端存储,也就是如果发送方是一个小端存储机器,那么它在网络通信数据传输时,就需要将数据从小端转换成大端,同理接收方如果也是小端,那么它在接收数据时,就需要将数据从大端转换成小端,这也就是网络字节序的概念。

注意: 如果我们的主机也是小端,那么我们在用户层编写代码时,也需要完成小端转大端的工作,所以此时操作系统为我们提供了一些接口,其中包括:htonl、ntohl(32位)/htons、ntohs(16位)(主机->网络/网络->主机),具体使用以后详谈。

认识socket编程接口

功能对应接口
创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)int socket(int domain, int type, int protocol);
绑定端口号 (TCP/UDP, 服务器)int bind(int socket, const struct sockaddr *address, socklen_t address_len);
开始监听socket (TCP, 服务器)int listen(int socket, int backlog);
接收请求 (TCP, 服务器)int accept(int socket, struct sockaddr* address, socklen_t* address_len);
建立连接 (TCP, 客户端)int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

(上述接口下篇博客我们重点介绍以及使用)

总结:socket相关知识今天我们就介绍到这,具体有关socket编程有待下篇博客见,See you!

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

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

相关文章

XXL-JOB任务调度中心后台命令执行漏洞

漏洞描述 XXL-JOB任务调度中心后台存在命令执行漏洞,攻击者可在后台通过写入shell命令任务调度获取服务器控制权限 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权…

AndroidAGP8.1.0和JDK 17迁移之旅

AndroidAGP8.1.0和JDK 17迁移之旅 前言: 由于我最近写demo的直接把之前的项目从AGP4.2.2升级到8.1.0引发了一些列问题,这里记录一下,前面讲解过迁移DSL方式遇到的问题,这次升级8.1.0也比之前顺利多了,想看DSL迁移的可…

Edge浏览器免费使用GPT3.5

搜索sider,安装Sidebar插件 注册账号即可每天免费使用30次。 Sider: ChatGPT侧边栏,GPT-4, 联网, 绘图

Excel VBA 复制除指定工作表外所有的工作表的内容到一张工作表中

当我们有一张表里面有很多sheet 具有相同的表结构,如果需要汇总到一张表中,那么我们可以借助VBA 去实现汇总自动化 Sub 复制所有工作表内容()Dim ws As WorksheetDim targetSheet As WorksheetDim lastRow As Long 设置目标表格,即要将所有…

SpringMVC之@RequestMapping注解

文章目录 前言一、RequestMapping介绍二、详解(末尾附源码,自行测试)1.RequestMapping注解的位置2.RequestMapping注解的value属性3.RequestMapping注解的method属性4.RequestMapping注解的params属性(了解)5.RequestM…

课程项目设计--项目建立--宿舍管理系统--springboot后端

前要 项目设计–宿舍管理系统 文章目录 项目建立导入依赖配置文件配置目录结构config配置mybatis-plusswagger 生成实体、mapper和servicebaseEntity统一响应实例响应码接口响应码接口实现统一响应result统一分页响应 项目建立 太长了,修改一下 导入依赖 暂时先加…

Java 项目日志实例:Log4j2

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ Apache Log4j 2 是对 Log4j 的升级,与其前身 Log4j 1.x 相比有了显着的改进,并提供了许多 Logback 可用的改进,同时支持 JCL 以及 SLF4J…

Word中对象方法(Methods)的理解及示例(上)

【分享成果,随喜正能量】奋斗没有终点,任何时候都是一个起点,沉潜是为了蓄势待发,沉潜是为了等待因缘。鲸豚沉潜于大海,幽兰深藏于山谷,能够经得起沉潜的人,才会有更高的成就。正如一年的树木只能当柴烧&am…

C++入门:函数缺省参数与函数重载

目录 1.函数缺省参数 1.1 缺省参数概念 1.2 缺省参数分类 2.函数重载 2.1 函数重载概念 2.2 C支持函数重载的原理 1.函数缺省参数 1.1 缺省参数概念 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的…

Unity 之 RaycastHit(存储射线投射操作)

文章目录 总述具体使用场景 总述 RaycastHit 类是 Unity 中的一个结构,用于存储射线投射操作的结果。射线投射是一种常用的技术,用于检测场景中的碰撞、获取碰撞点、获取碰撞对象的信息等。RaycastHit 提供了关于射线与场景中对象的交互信息&#xff0c…

新型Windows内核池风水利用工具研究

引用 这篇文章的目的是介绍一种新型基于内核态分页内存和非分页内存的越界写入通用利用技术和相关工具复现. 文章目录 引用简介分页模式利用分析分页模式利用调试分析非分页模式利用分析非分页模式利用调试分析工具使用方法工具使用效果相关引用参与贡献 简介 笔者的在原作者利…

硕士研究生小论文写作方法

本人985硕博毕业-曾多次辅导本硕同学完成成毕设,下面分享一些经验 图为当年大论文外审结果!!! 当撰写一篇硕士研究生的小论文时,以下是每个部分的写作方法的详细描述,: 摘要(Abst…

零基础在家就可以做的副业,3个兼职项目推荐

做副业最需要注重的是什么?我觉得有收益,稳定,上手快,可以学到东西,下面3个副业适合新手快速变现的副业,大可以随便挑一两个尝试一下 第一个:在小红书的发手记 满5000粉丝们就可以申请品牌合作…

OMT画图的五种结构表达方式

实例化:A类依赖于B类。 class B {doSth () {} }class A {constructor () {}run () {const b new B()b.doSth()} }new A().run()委托:A对象依赖于B对象。 class B {doSth () {} } const b new B()class A {constructor () {}run () {b.doSth()} } new A…

为什么 Lemon8 是今年值得关注的社交媒体应用?

社交媒体应用逐渐成为了用户联系亲朋好友的一种方式,也成为了营销推广有利的平台。近期,Lemon8也快速崛起,一度荣登美国APP下载排行榜前十名,在社交和电子商务市场中,也占据了很大的份额,在日本以及泰国多地更为流行。为什么Lemon8会成为最值得关注的社交媒体应用呢? 什么原因…

基于springboot+vue的博物馆藏品平台(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

TouchGFX之安装

1.安装X-CUBE-TOUCHGFX​ 帮助 ->管理嵌入式软件包 转到“STMicroelectronics”选项卡。 滚动直至找到“X-CUBE-TOUCHGFX”,然后展开节点。 点击“TouchGFX Generator”复选框,然后点击“立即安装”。 将下载软件包并显示许可协议。 找到TouchGFX Gen…

(成功踩坑)electron-builder打包过程中报错

目录 注意:文中的解决方法2,一定全部看完,再进行操作,有坑 背景 报错1: 报错2: 1.原因:网络连接失败 2.解决方法1: 3.解决方法2: 3.1查看缺少什么资源文件 3.2去淘…

PostgreSQL基本操作总结

安装按PostgreSQL数据库后,会默认创建用户postgres和数据库postgres,这个用户是超级用户,权限最高,可以创建其他用户和权限,在实际开发过程中,会新创建用户和业务数据库,本文主要介绍用户权限和…

Vue中DOM的更新为什么是异步的?

在 Vue 中,DOM 的更新是异步的机制是为了优化性能和提升用户体验。这个机制被称为“异步更新队列”。 Vue的异步更新队列机制是其实现高效渲染的关键。它通过将多次数据变化合并到一个批处理中,从而减少了不必要的DOM操作,提高了性能。下面是…