网站建设技术包括,做物流用哪个网站好,网站开发的技术意义,微信公众号开发者中心引言#xff1a;
北京时间#xff1a;2023/8/12/15:32#xff0c;自前天晚上更新完文章#xff0c;看了一下鹅厂新出的《扫毒3》摆烂至现在#xff0c;不知道是长大了#xff0c;还是近年港片就那样#xff0c;给我的感觉不是很好#xff0c;也可能是国内市场对港片不…引言
北京时间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、ntohl32位/htons、ntohs16位主机-网络/网络-主机具体使用以后详谈。
认识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