linux -网络编程一网络基本概念和Socket编程

目录

1 网络基础概念

1.1 协议

1.2分层模型

1.3 数据通信过程

1.4 网络应用程序的设计模式

1.5 以太网帧格式

1.6网络名词术语解析(自行阅读扫盲)

2 SOCKET编程

 2.1 socket编程预备知识

2.2 socket编程主要的API函数介绍

目标:

  • 了解OSI七层、TCP/IP四层模型结构
  • 了解常见网络协议格式
  • 掌握网络字节序和主机字节序之间的转换(大端法和小端法)
  • 说出TCP服务器端通信流程
  • 说出TCP客户端通信流程
  • 独立写出TCP服务器端代码
  • 独立写出TCP客户端代码

1 网络基础概念

1.1 协议

        

概念: 协议事先约定好, 大家共同遵守的一组规则, 如交通信号灯.从应用程序的角度看, 协议可理解为数据传输和数据解释的规则;可以简单的理解为各个主机之间进行通信所使用的共同语言.假设,A、B双方欲传输文件。规定:

第一次: 传输文件名,接收方接收到文件名,应答OK给传输方;

第二次: 发送文件的尺寸,接收方接收到该数据再次应答一个OK;

第三次: 传输文件内容。同样,接收方接收数据完成后应答OK表示文件内 容接收成功。

 这种在A和B之间被遵守的协议称之为原始协议, 后来经过不断增加完善改进, 最终形成了一个稳定的完整的传输协议, 被广泛应用于各种文件传输, 该协议逐渐就成了一个标准协议.

几种常见的协议

传输层 常见协议有TCP/UDP协议。

应用层 常见的协议有HTTP协议,FTP协议。

网络层 常见协议有IP协议、ICMP协议、IGMP协议。

网络接口层 常见协议有ARP协议、RARP协议。

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

UDP用户数据报协议(User Datagram Protocol)是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

HTTP超文本传输协议(Hyper Text Transfer Protocol)是互联网上应用最为广泛的一种网络协议

FTP文件传输协议(File Transfer Protocol)

IP协议是因特网互联协议(Internet Protocol)

ICMP协议是Internet控制报文协议(Internet Control Message Protocol)它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。

IGMP协议是 Internet 组管理协议(Internet Group Management Protocol),是因特网协议家族中的一个组播协议。该协议运行在主机和组播路由器之间。

ARP协议是正向地址解析协议(Address Resolution Protocol),通过已知的IP,寻找对应主机的MAC地址。

RARP是反向地址转换协议,通过MAC地址确定IP地址。

1.2分层模型

        

OSI是Open System Interconnection的缩写, 意为开放式系统互联. 国际标准化组织(ISO)制定了OSI模型, 该模型定义了不同计算机互联的标准, 是设计和描述计算机网络通信的基本框架.

网络分层 OSI 7层模型: 物数网传会表应 

  • 物理层---双绞线,光纤(传输介质),将模拟信号转换为数字信号
  • 数据链路层---数据校验,定义了网络传输的基本单位-帧 
  • 网络层---定义网络,两台机器之间传输的路径选择点到点的传输
  • 传输层---传输数据 TCP,UDP,端到端的传输  
  • 会话层---通过传输层建立数据传输的通道. 
  • 表示层---编解码,翻译工作.

应用层---为客户提供各种应用服务,email服务,ftp服务,ssh服务

 

1.3 数据通信过程

通信过程: 其实就是发送端层层打包, 接收方层层解包.

注意: 这些操作不是用户自己做的, 而是底层帮我们做好的.

1.4 网络应用程序的设计模式

        

  • C/S设计模式优缺点:

优点:

客户端在本机上可以保证性能, 可以将数据缓存到本地, 提高数据的传输效率, 提高用户体验效果.

客户端和服务端程序都是由同一个开发团队开发, 协议选择比较灵活.

缺点:服务器和客户端都需要开发,工作量相对较大, 调试困难, 开发周期长;从用户的角度看, 需要将客户端安装到用户的主机上, 对用户主机的安 全构成威胁.

  • B/S设计模式优缺点:

优点:

无需安装客户端, 可以使用标准的浏览器作为客户端;只需要开发服务器,工作量相对较小;

由于采用标准的客户端, 所以移植性好, 不受平台限制相对安全,不用安装软件

缺点:由于没有客户端, 数据缓冲不尽人意, 数据传输有限制, 用户体验较差;通信协议选择只能使用HTTP协议,协议选择不够灵活;

1.5 以太网帧格式

        以太网帧格式就是包装在网络接口层(数据链路层)的协议。

 以ARP为例介绍以太网帧格式

        

目的端mac地址是通过发送端发送ARP广播, 接收到该ARP数据的主机先判断是否是自己的IP, 若是则应答一个ARP应答报文, 并将mac地址填入应答报文中; 若目的IP不是自己的主机IP, 则直接丢弃该ARP请求报文. 

详细讲解ARP协议

        

 IP段格式

 IP段格式

16位总长度: 最大65536

8位生存时间ttl(网络连接下一跳的次数): 为了防止网络阻塞

32位源ip地址, 共个4字节!我们熟悉的ip都是点分十进制的,4字节, 每字节对应一个点分位,最大为255 ,实际上就是整形数!

32位目的ip地址 

8位协议: 用来区分上层协议是TCP, UDP, ICMP还是IGMP协议.

16位首部校验和: 只校验IP首部, 数据的校验由更高层协议负责.

UDP数据报格式

        通过IP地址来确定网络环境中的唯一的一台主机;

        主机上使用端口号来区分不同的应用程序.

        IP+端口唯一确定唯一一台主机上的一个应用程序.

TCP数据流格式:

稳定的, 安全的, 可靠的

序号: TCP是安全可靠的, 每个数据包都带有序号, 当数据包丢失的时候, 需要重传, 要使用序号进行重传. 控制数据有序, 丢包重传.

确认序号: 使用确认序号可以知道对方是否已经收到了, 通过确认序号可以知道哪个序号的数据需要重传.

16位窗口大小--滑动窗口(主要进行流量控制)

1.6网络名词术语解析(自行阅读扫盲)

2 SOCKET编程

        传统的进程间通信借助内核提供的IPC机制进行, 但是只能限于本机通信, 若要跨机通信, 就必须使用网络通信.( 本质上借助内核-内核提供了socket伪文件的机制实现通信----实际上是使用文件描述符), 这就需要用到内核提供给用户的socket API函数库.

        

既然提到socket伪文件, 所以可以使用文件描述符相关的函数read write

可以对比pipe管道讲述socket文件描述符的区别.

使用socket会建立一个socket pair.

如下图, 一个文件描述符操作两个缓冲区, 这点跟管道是不同的, 管道是两个文件描述符操作一个内核缓冲区.

 

 2.1 socket编程预备知识

网络字节序:

大端和小端的概念

大端: 低位地址存放高位数据, 高位地址存放低位数据

小端: 低位地址存放低位数据, 高位地址存放高位数据

大端和小端的使用使用场合???

大端和小端只是对数据类型长度是两个及以上的, 如int  short, 对于单字节 没限制, 在网络中经常需要考虑大端和小端的是IP和端口.

思考题: 0x12345678如何存放???

如何验证本机上大端还是小端??-----使用共用体.

编写代码endian.c进行测试, 测试本机上是大端模式还是小端模式?

网络传输用的是大端法, 如果机器用的是小端法, 则需要进行大小端的转换.

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
#include<string.h>
#include <arpa/inet.h>
#include <netinet/in.h>union{short s;char c[sizeof(short)];
} un2;union {int s;char c[sizeof(int)];
} un4;int main()
{printf("[%d][%d][%d]\n",sizeof(short),sizeof(int),sizeof(long int));//测试short 类型un2.s=0x0102;printf("%d,%d,%d\n",un2.c[0],un2.c[1],un2.s);//测试 int 类型// un4.s=0x01020304;un4.s=0x1245678;printf("%d,%d,%d,%d\n",un4.c[0],un4.c[1],un4.c[2],un4.c[3],un4.s);return 0;
}
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{union {short s;char c[sizeof(short)];} un;un.s = 0x0102;if(sizeof(short)==2) {if(un.c[0]==1 && un.c[1] == 2){printf("big-endian\n");}else if (un.c[0] == 2 && un.c[1] == 1){printf("little-endian\n");}else{printf("unknown\n");}} else{printf("sizeof(short)= %d\n",sizeof(short));}return 0;
}

下面4个函数就是进行大小端转换的函数:

   #include <arpa/inet.h>

       uint32_t htonl(uint32_t hostlong);

       uint16_t htons(uint16_t hostshort);

       uint32_t ntohl(uint32_t netlong);

       uint16_t ntohs(uint16_t netshort);

函数名的h表示主机host, n表示网络network, s表示short, l表示long

上述的几个函数, 如果本来不需要转换函数内部就不会做转换.

P地址转换函数:

p->表示点分十进制的字符串形式

to->到

n->表示network网络

int inet_pton(int af, const char *src, void *dst);

函数说明: 将字符串形式的点分十进制IP转换为大端模式的网络IP(整形4字节数)

参数说明:

af: AF_INET

src: 字符串形式的点分十进制的IP地址

dst: 存放转换后的变量的地址

例如: inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);

手工也可以计算: 如192.168.232.145, 先将4个正数分别转换为16进制数,

192--->0xC0  168--->0xA8   232--->0xE8   145--->0x91

最后按照大端字节序存放: 0x91E8A8C0, 这个就是4字节的整形值.

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

函数说明: 网络IP转换为字符串形式的点分十进制的IP

参数说明:

af: AF_INET

src: 网络的整形的IP地址

dst: 转换后的IP地址,一般为字符串数组

size: dst的长度

返回值:

成功--返回指向dst的指针

失败--返回NULL, 并设置errno

例如: IP地址为010aa8c0, 转换为点分十进制的格式:

01---->1    0a---->10   a8---->168   c0---->192

由于从网络中的IP地址是高端模式, 所以转换为点分十进制后应该为: 192.168.10.1

socket编程用到的重要的结构体:struct sockaddr

struct sockaddr结构说明:

   struct sockaddr {

        sa_family_t sa_family;

        char     sa_data[14];

   }

struct sockaddr_in结构:

struct sockaddr_in {

         sa_family_t    sin_family; /* address family: AF_INET */

         in_port_t      sin_port;   /* port in network byte order */

         struct in_addr sin_addr;   /* internet address */

   };

   /* Internet address. */

   struct in_addr {

         uint32_t  s_addr;     /* address in network byte order */

   };  //网络字节序IP--大端模式

通过man 7 ip可以查看相关说明

2.2 socket编程主要的API函数介绍

int socket(int domain, int type, int protocol);

函数描述: 创建socket

参数说明:

domain: 协议版本

AF_INET IPV4

AF_INET6 IPV6

AF_UNIX AF_LOCAL本地套接字使用

type:协议类型

SOCK_STREAM 流式, 默认使用的协议是TCP协议

SOCK_DGRAM  报式, 默认使用的是UDP协议

protocal:

一般填0, 表示使用对应类型的默认协议.

返回值:

成功: 返回一个大于0的文件描述符

失败: 返回-1, 并设置errno

当调用socket函数以后, 返回一个文件描述符, 内核会提供与该文件描述符相对应的读和写缓冲区, 同时还有两个队列, 分别是请求连接队列和已连接队列.

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

函数描述: 将socket文件描述符和IP,PORT绑定

参数说明:

socket: 调用socket函数返回的文件描述符

addr: 本地服务器的IP地址和PORT,

struct sockaddr_in serv;

serv.sin_family = AF_INET;

serv.sin_port = htons(8888);

//serv.sin_addr.s_addr = htonl(INADDR_ANY);

//INADDR_ANY: 表示使用本机任意有效的可用IP

inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);

addrlen: addr变量的占用的内存大小

返回值:

成功: 返回0

失败: 返回-1, 并设置errno

int listen(int sockfd, int backlog);

函数描述: 将套接字由主动态变为被动态

参数说明:

sockfd: 调用socket函数返回的文件描述符

backlog: 同时请求连接的最大个数(还未建立连接)

返回值:

成功: 返回0

失败: 返回-1, 并设置errno

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

函数说明:获得一个连接, 若当前没有连接则会阻塞等待.

函数参数:

sockfd: 调用socket函数返回的文件描述符

addr: 传出参数, 保存客户端的地址信息

addrlen: 传入传出参数,  addr变量所占内存空间大小

返回值:

成功: 返回一个新的文件描述符,用于和客户端通信

失败: 返回-1, 并设置errno值.

accept函数是一个阻塞函数, 若没有新的连接请求, 则一直阻塞.

从已连接队列中获取一个新的连接, 并获得一个新的文件描述符, 该文件描述符用于和客户端通信.  (内核会负责将请求队列中的连接拿到已连接队列中)

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

函数说明: 连接服务器

函数参数:

sockfd: 调用socket函数返回的文件描述符

addr: 服务端的地址信息

addrlen: addr变量的内存大小

返回值:

成功: 返回0

失败: 返回-1, 并设置errno值

接下来就可以使用write和read函数进行读写操作了.

除了使用read/write函数以外, 还可以使用recv和send函数

读取数据和发送数据:

ssize_t read(int fd, void *buf, size_t count);

ssize_t write(int fd, const void *buf, size_t count);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

对应recv和send这两个函数flags直接填0就可以了.

注意: 如果写缓冲区已满, write也会阻塞, read读操作的时候, 若读缓冲区没有数据会引起阻塞.

使用socket的API函数编写服务端和客户端程序的步骤图示:

根据服务端和客户端编写代码的流程, 编写代码并进行测试.

测试过程中可以使用netstat命令查看监听状态和连接状态

netstat命令:

a表示显示所有,

n表示显示的时候以数字的方式来显示

p表示显示进程信息(进程名和进程PID)

作业:

自己编写代码熟悉一下服务端和客户端的代码开发流程;

设计服务端和客户端通信协议(属于业务层的协议)如发送结构体

typedef struct teacher_{int tid;char name[30];int age;char sex[30];int sal;
} teacher;typedef struct student_{int sid;char name[30];int age;char sex[30];
}student;typedef struct SendMsg_{int type;//1 - teacher;2 - studentint len;//char buf[0];//变长发送数据
}SendMsg;

服务端

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h> //toupper() 函数的使用
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>// #service codeint main()
{// 1.create socket int lfd = socket(AF_INET, SOCK_STREAM, 0);if (lfd < 0){perror("socket error");return -1;}struct sockaddr_in serv;bzero(&serv, sizeof(serv));serv.sin_family = AF_INET;serv.sin_port = htons(8888);              // not chose 1024之前的结果。将高端字节序转换成网络字节序。serv.sin_addr.s_addr = htonl(INADDR_ANY); // 表示使用本级的任意ip// 2.bindint ret = bind(lfd, (struct sockaddr *)&serv, sizeof(serv));if (ret < 0){perror("bind error");return -1;}// 3.listen 监听数据listen(lfd, 128);struct sockaddr_in client;socklen_t len=sizeof(client);int cfd=accept(lfd,(struct sockaddr *)&client,&len);//len 是一个输入输出参数char sIP[16];printf("client -->IP:[%s],client -->Port:[%d]\n",inet_ntop(AF_INET,&client.sin_addr.s_addr,sIP,sizeof(sIP)),ntohs(client.sin_port));// 4.accept accept 不是新建一个连接,而是从一个连接里面拿出来一个连接出俩而已int cfd = accept(lfd, NULL, NULL);printf("lfd==[%d],cfd==[%d]\n", lfd, cfd);// while() read writeint n = 0;int i = 0;char buf[1024];// while(" nihaowhile (1){// 读数据memset(buf, 0x00, sizeof(buf));n = read(cfd, buf, sizeof(buf)); // 阻塞函数if (n <= 0){printf("read error or client connection close\n", n);}printf("n==[%d],buf==[%s]\n", n, buf);for (i = 0; i < n; i++){buf[i] = toupper(buf[i]);}}// write datawrite(cfd, buf, n);// 关闭监听文件描述符和通信文件描述符close(lfd);close(cfd);return 0;
}

客户端

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>int main()
{// 创建socket --用于和服务端进行通信int cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd < 0){perror("socket error");return -1;}// 连接服务器  int connect(int sockfd, const struct sockaddr *addr,//      socklen_t addrlen);struct sockaddr_in serv;serv.sin_family = AF_INET;serv.sin_port = htons(8888);inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);int id = connect(cfd, (struct sockaddr *)&serv, sizeof(serv));if (id < 0){perror("connection error");return -1;}int n = 0;char buf[256];while (1){// 读标准输入数据memset(buf, 0x00, sizeof(buf));n = read(STDIN_FILENO, buf, sizeof(buf));// 发送数据write(cfd, buf, n);// 读服务端发过来读数据memset(buf, 0x00, sizeof(buf));n = read(STDIN_FILENO, buf, sizeof(buf));if(n<=0){printf("read error or service close,n==[%d]",n);return -1;}printf("n==[%x],buf==[%s]\n", n, buf);}//关闭a套接字close(cfd);return 0;
}

测试:

1.0 使用nc -ip -port 测试

开启一个shell 服务端先开启

另外开启一个shell 客户端 

2.0 使用客户端的代码测试

使用客户端的代码测试,等待一分钟,开启服务端代码,再另建一个窗口开启客户端代码,最后卡其通信测试一下。

客户端的代码

服务端的代码

补充:

端口对应的表

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

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

相关文章

【vue】 前端vue2 全局水印效果

最近写项目遇到一个需求&#xff0c;全局显示水印&#xff0c;不管在哪个路由都要显示。 想要实现的效果&#xff1a; 新建shuiyin.js文件 // 定义水印函数 const addWatermark ({container document.body, // 水印添加到的容器&#xff0c;默认为 bodywidth "200px&…

MaxPatrol SIEM 增加了一套检测供应链攻击的专业技术

我们为 MaxPatrol SIEM 信息安全事件监控系统增加了一套新的专业技术。 该产品可帮助企业防范与供应链攻击相关的威胁。 此类攻击正成为攻击者的首要目标&#xff1a;它们以软件开发商和供应商为目标&#xff0c;网络犯罪分子通过他们的产品进入最终目标的基础设施。 因此&a…

新版塔罗占卜网站源码八字合婚风水起名附带搭建视频

新版塔罗占卜网站源码八字合婚风水起名PHP源码附带搭建视频,附带文本教学及视频教程安装方法以linux为例: 1、建议在服务器上面安装宝塔面板,以便操作,高逼格技术员可以忽略这步操作。 2、把安装包文件解压到根目录,同时建立数据库,把数据文件导入数据库 3、修改核心文件…

安达发|APS智能排程软件推动企业智能转型

随着智能化技术的飞速发展&#xff0c;企业在构建智能计划排产规划方面有了新的可能性。APS排程软件&#xff08;Advanced Planning and Scheduling&#xff09;作为一种强大的工具&#xff0c;为企业提供了实现智能计划排产规划的新模式&#xff0c;主要是利用计算机运算速度快…

无线电蓝牙音频-BES数字音频系统音频流图

+我V hezkz17进数字音频系统研究开发交流答疑群(课题组) (1)音乐播放音频流图 Decode"(解码)是指将编码后的数据转换回原始格式或可读取的形式的过程,SBC解码成PCM

06 HTTP(下)

06 HTTP&#xff08;下&#xff09; 介绍服务器如何响应请求报文&#xff0c;并将该报文发送给浏览器端。介绍一些基础API&#xff0c;然后结合流程图和代码对服务器响应请求报文进行详解。 基础API部分&#xff0c;介绍stat、mmap、iovec、writev。 流程图部分&#xff0c;描…

linux 安装FTP

检查是否已经安装 $] rpm -qa |grep vsftpd vsftpd-3.0.2-29.el7_9.x86_64出现 vsftpd 信息表示已经安装&#xff0c;无需再次安装 yum安装 $] yum -y install vsftpd此命令需要root执行或有sudo权限的账号执行 /etc/vsftpd 目录 ftpusers # 禁用账号列表 user_list # 账号列…

集成kisso框架springboot解决登录不了问题

前端使用 VUE 框架&#xff0c;要求请求头中传入 token值&#xff0c;获取设置token使用cookie操作 import Cookies from js-cookieconst TokenKey token-c export function getToken() {return Cookies.get(TokenKey) } export function setToken(token) {Cookies.set(Token…

html学习3(表格table、列表list)

1、html表格由<table>标签来定义。 <thead>用来定义表格的标题部分&#xff0c;其内部用 <th > 元素定义列的标题&#xff0c;可以使其在表格中以粗体显示&#xff0c;与普通单元格区分开来。<tbody>用来定义表格的主体部分&#xff0c;其内部用<t…

无涯教程-jQuery - Tabs组件函数

窗口小部件选项卡函数可与JqueryUI中的窗口小部件一起使用。选项卡用于在分成逻辑部分的内容之间交换。 Tabs - 语法 $( "#tabs" ).tabs(); Tabs - 示例 以下是显示Tab用法的简单示例- <!doctype html> <html lang"en"><head><m…

【文生图系列】Runaway Gen-2试用体验

文章目录 风景示例动物示例人物动作示例 Runway旗下的视频生成产品Gen-1和Gen-2已彻底开放&#xff0c;任何人都可注册一个账号免费尝试。免费的时长是105s&#xff0c;每个视频生成4s。 看gen-2官网和各公众号放出来的示例&#xff0c;非常震撼&#xff0c;不禁感慨现在文生视…

Ubuntu Server版 之 apache系列 常用配置 以及 隐藏 版本号 IP、Port 搭建服务案例

查看版本 旧的 用 httpd -v 新的 用 apache2 -v 配置检测 旧的 httpd -t 新的 apachectl configtest window用的apache 是 httpd -t Linux 中 apachectl configtest 主配置文件 之前旧版apache 是httpd 现在都改成 apache2 /etc/apache2/apache2.conf window中 httpd.con…

Git全栈体系(三)

第六章 GitHub 操作 一、创建远程仓库 二、远程仓库操作 命令名称作用git remote -v查看当前所有远程地址别名git remote add 别名 远程地址起别名git push 别名 分支推送本地分支上的内容到远程仓库git clone 远程地址将远程仓库的内容克隆到本地git pull 远程库地址别名 远…

【C++】模板进阶(模板的特化,非类型模板参数,模板的分离编译)

文章目录 一、模板使用时一定要加typename的情况二、 非类型模板参数三、模板的特化1.函数模板特化2.类模板特化1.全特化&#xff1a;2. 偏特化&#xff1a;1. 部分特化2.参数更一步限制 四、模板的分离编译1.Stack.h2.Stack.cpp(定义)3.test.cpp 一、模板使用时一定要加typena…

TSINGSEE青犀视频汇聚平台EasyCVR多种视频流播放协议介绍

众所周知&#xff0c;TSINGSEE青犀视频汇聚平台EasyCVR可支持多协议方式接入&#xff0c;包括主流标准协议GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。今天我们来说一说&#xff0c;EasyCVR平台支持分…

maven本地仓库地址修改+maven国内镜像设置+maven运行所需pos.xml文件配置基本写法

1&#xff0c;maven本地仓库地址修改 maven在使用过程中&#xff0c;本地项目仓库其空间占用会越来越大&#xff0c;但是其默认仓库位置往往是以C盘为主&#xff0c;C盘作为系统盘常常会遇到所在盘空间占满的情况&#xff0c;所以我们将其改至其他硬盘空间位置为适合做法&#…

二十三种设计模式第二十三篇--状态模式

状态模式&#xff0c;是一种行为模式&#xff0c;在软件开发过程中&#xff0c;对象按照不同的情况做出不同的行为&#xff0c;我们把这样的对象称为具有状态的对象&#xff0c;而把影响对象行为的一个或者多个动态变化的属性称为状态。 对这种具有状态的对象变成&#xff0c;…

【kubernetes】k8s单master集群环境搭建及kuboard部署

k8s入门学习环境搭建 学习于许大仙: https://www.yuque.com/fairy-era k8s官网 https://kubernetes.io/ kuboard官网 https://kuboard.cn/ 基于k8s 1.21.10版本 前置环境准备 一主两从&#xff0c;三台虚拟机 CPU内存硬盘角色主机名IPhostname操作系统4C16G50Gmasterk8s-mast…

JVM面试题--JVM组成

JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 运行流程 什么是程序计数器&#xff1f; 程序计数器&#xff1a;线程私有的&#xff0c;内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。 我们知道ja…

第4章 .NetCore程序通过花生壳实现内网穿透

.NetCore程序在调试环境中都是基于内网的&#xff0c;但是.NetCore程序如果需要集成微信第3方认证程序&#xff0c;由于微信第3方认证程序需要外网把认证后的数据信息&#xff0c;通过外网传输到.NetCore程序中&#xff0c;所以必须先实现把内网地址映射为外网地址这样的操作叫…