网站设计公司 知道万维科技/seo技术代理
前言:本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以, 我们主要就是要实现客户端以及服务端的逻辑代码。 那么, 接下来开始我们的学习吧。
ps:本节内容建议了解socket套接字的接口的友友们进行观看哦,本节内容中涉及到的接口都不会讲解, 直接就用了。
目录
整体代码
Udpclient
UdpServer
main(配合UdpServer, UdpServer的入口)
准备文件
实现步骤
实现服务端客户端的收发消息
Udpserver
Init函数
run函数
UdpServer析构
Udpclient
实现客户端之间的聊天功能
Udpserver
Udpclient
运行结果
整体代码
先上整体代码:
Udpclient
#include<iostream>
using namespace std;
#include<string>
#include<sys/types.h>
#include"Log.hpp"
#include<sys/socket.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<string.h>
#include<netinet/in.h>
Log lg;class ThreadData
{
public:sockaddr_in server;int sockfd;
};void* recv_message(void* args)
{char buffer[1024];ThreadData* td = static_cast<ThreadData*>(args); while (true){//接收数据sockaddr_in temp;socklen_t len;string info;ssize_t s = recvfrom(td->sockfd, buffer, sizeof(buffer) - 1, 0, (sockaddr*)&temp, &len);if (s < 0){lg(Error, "recv error, error: %d, strerror: %s", errno, strerror(errno));continue;}buffer[s] = 0;info = buffer;cout << info << endl;}}void* send_message(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);string message;while (true){ getline(cin, message); //获取数据//发送数据sendto(td->sockfd, message.c_str(), message.size(), 0, (sockaddr*)&td->server, sizeof(td->server));}
}int main(int argc, char* argv[])
{if (argc != 3){cout << "Client server" << endl;}//先拿到套接字的参数string serverip = argv[1];uint16_t serverport = stoi(argv[2]);ThreadData td;//创建套接字与打开网卡memset(&td.server, 0, sizeof(td.server));td.server.sin_family = AF_INET;td.server.sin_port = htons(serverport);td.server.sin_addr.s_addr = inet_addr(serverip.c_str());td.sockfd = socket(AF_INET, SOCK_DGRAM, 0); //创建文件描述符, 网卡的文件描述符, 网络传输就是使用网络文件描述符找到对应的文件内的数据if (td.sockfd < 0){lg(Error, "client create sockfd error, errno: %d, strerror: %s", errno, strerror(errno));exit(1);}//创建线程, 然后运行线程, 等待线程pthread_t recv, send;pthread_create(&recv, nullptr, recv_message, &td);pthread_create(&send, nullptr, send_message, &td);pthread_join(recv, nullptr);pthread_join(send, nullptr);close(td.sockfd);return 0;
}
UdpServer
#include<iostream>
using namespace std;
#include<sys/types.h>
#include<string>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<strings.h>
#include"Log.hpp"
#include<functional>
#include<netinet/in.h>
#include<unordered_map>int defaultport = 8080;
string defaultip = "0.0.0.0";using func_t = function<string(string, sockaddr_in&, unordered_map<string, sockaddr_in>&)>;
Log lg;enum
{SockError = 2,BindError = 3,RecvError = 4,
};class UdpServer
{
public:UdpServer(uint16_t port = defaultport) : port_(port), ip_(defaultip), isrunning_(false){}void Init(){//先创建套接字变量并且完成初始化。 然后就创建网卡文件sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(port_);local.sin_addr.s_addr = inet_addr(ip_.c_str());sockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){lg(Fatal, "create sock error, errno: %d, strerror: %s", errno, strerror(errno));exit(SockError);}lg(Info, "create sock success");//绑定if (bind(sockfd_, (sockaddr*)&local, sizeof(local)) < 0) {lg(Fatal, "bind error, errno: %d, strerror: %s", errno, strerror(errno));exit(BindError);}lg(Info, "bind success");}void BroadCast(string message, unordered_map<string, sockaddr_in>& clients){cout << "1 "<< endl;for (auto& e : clients){sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)&e.second, sizeof(e.second));}cout << "2 " << endl;}void run(func_t func){isrunning_ = true;char inbuffer[1024];while (isrunning_){memset(inbuffer, 0, sizeof(inbuffer));sockaddr_in client;socklen_t client_len;memset(&client, 0, sizeof(client));//接收数据的同时监听到客户端的来源ssize_t s = recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)&client, &client_len);if (s < 0) {lg(Waring, "recvfrom error, errno: %d, strerror: %s", errno, strerror(errno));continue;}inbuffer[s] = 0;//处理数据//创建套接字, 用来监听是哪一个客户端string message = inbuffer;message = func(message, client, clients);//处理完成后, 返回发送给客户端BroadCast(message, clients);// sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)&client, sizeof(client));}}~UdpServer(){if (sockfd_ > 0) close(sockfd_); }
private:int sockfd_;uint16_t port_;string ip_;bool isrunning_;unordered_map<string, sockaddr_in> clients;};
main(配合UdpServer, UdpServer的入口)
#include"UdpServer.hpp"
#include<memory>string Handler(string message, sockaddr_in& client, unordered_map<string, sockaddr_in>& clients)
{string tmp = inet_ntoa(client.sin_addr) + to_string(client.sin_port);if (!clients.count(tmp)){clients[tmp] = client; cout << "ip " << inet_ntoa(client.sin_addr) << " : port " << client.sin_port << " has add in talk room" << endl;}message = "[" + string(inet_ntoa(client.sin_addr)) + ":" + to_string(client.sin_port) + "]#: " + message; return message;
}int main(int argc, char* argv[])
{if (argc != 2){cout << "has return" << endl;return 1;}//uint16_t serverport = stoi(argv[1]); unique_ptr<UdpServer> svr(new UdpServer(serverport));//svr->Init();svr->run(Handler);return 0;
}
准备文件
我们要准备三个文件
- Udpclient.cc——用来运行起来客户端
- UdpServer.hpp——用来实现服务端的各种接口
- main.cc——用来运行起来服务端
除了这三个主要的文件。 其实博主还准备了两个可以忽略的文件(为了方便)。 一个是博主自己写的日志程序, 用来打印日志。 一个是makefile, 方便编译。
如果没有日志程序的话,打印错误信息时直接cout, printf打印即可。 makefile建议带上, 方便编译养成好习惯。
实现步骤
注意, 一步到位是很难的。 所以我们先实现简单的功能, 再实现困难的功能。
这里简单的功能就是,先让客户端能够将数据发给服务端了, 然后服务端接收到消息后再将数据返回给客户端。
这里困难的功能就是当多个客户端如何看到互相的信息。然后如何能够一遍发信息,一边收信息。
实现服务端客户端的收发消息
Udpserver
实现逻辑:Udpserver.hpp中封装一个类。这个类里面封装一些接口, 然后我们在main函数中创建类对象, 在执行接口操作。
所以, 先封装一个类, 将要实现的接口以及要用到的变量写上, 实现一个框架:
#include<iostream>
using namespace std;
#include<string>int defaultport = 8080; //默认的端口号,我们要创建一个默认的端口号
string defaultip = "0.0.0.0"; //在服务器中使用套接字的时候, bind函数不能绑定公网IP, 因为
//服务器的公网IP可能是虚拟的, 注意,IP地址是和网卡挂钩的, 一个网卡只能有一个IP地址。
//绑定ip地址就是说在绑定网卡,也就是说绑定某个IP地址后就只能监听这一个网卡的消息了。 但是
//有些机器是有很多张网卡的, 所以就有一个默认IP:0.0.0.0, 绑定这个IP就能监听在本机器下面
//所有的网卡的信息。 Log lg;class UdpServer
{
public:UdpServer(uint16_t port = defaultport) : port_(port), ip_(defaultip), isrunning_(false){}void Init(){}void run(func_t func){}~UdpServer(){}
private:int sockfd_; //服务端的网卡文件的编号uint16_t port_; //服务器起来后的端口号string ip_; //服务器起来的时候所在的ip地址bool isrunning_; //服务器是否正在运行};
下面是main.cpp里面的内容, 直接启动服务端。
#include"UdpServer.hpp"
#include<memory>int main(int argc, char* argv[])
{if (argc != 2){cout << "has return" << endl;return 1;}//uint16_t serverport = stoi(argv[1]); unique_ptr<UdpServer> svr(new UdpServer(serverport));//svr->Init();svr->run();return 0;
}
Init函数
Udpserver里面的Init函数, 这个函数用来绑定服务端的套接字的。 什么是绑定? 博主目前的理解就是将我们运行的服务端这个程序能够和网卡建立起关系。
这个关系中, 关系的两端是我们运行的服务端程序和socket网卡文件(网卡文件就代表了网卡)。关系的纽带是ip地址和端口号。 利用ip地址和端口号来将我们的服务端程序绑定给网卡, 这个时候因为网卡的工作性质, 其他的进程都不能再绑定网卡了, 直到我们的服务端退出。
void Init(){//先创建套接字变量并且完成初始化。 然后就创建网卡文件sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(port_);local.sin_addr.s_addr = inet_addr(ip_.c_str());sockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){lg(Fatal, "create sock error, errno: %d, strerror: %s", errno, strerror(errno));exit(SockError);}lg(Info, "create sock success");//绑定if (bind(sockfd_, (sockaddr*)&local, sizeof(local)) < 0) {lg(Fatal, "bind error, errno: %d, strerror: %s", errno, strerror(errno));exit(BindError);}lg(Info, "bind success");}
run函数
我们这里思考一个问题, 我们要实现的其实是服务端与客户端之间收发消息。 所以, 我们就要客户端先发, 然后服务端收消息。
然后! 服务端收到消息将消息 处理一下 再将消息发回客户端。
所以,这个过程中服务端有三个主要的动作, 一个是收,一个是处理, 一个是发。
然后我们的处理怎么处理, 我们可以将处理动作暴露出去, 交给main.cpp来决定。 ——利用回调函数, main.cpp中将要执行的动作作为函数传给run函数。
如下为接口:
//这里的func_t是一个回调函数的类型。 什么类型, 使用包装器包装的!注意//包含头文件functionalusing func_t = function<string(string)>; void run(func_t func){isrunning_ = true;char inbuffer[1024];while (isrunning_){memset(inbuffer, 0, sizeof(inbuffer));sockaddr_in client;socklen_t client_len;memset(&client, 0, sizeof(client));//接收数据的同时监听到客户端的来源ssize_t s = recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)&client, &client_len);if (s < 0) {lg(Waring, "recvfrom error, errno: %d, strerror: %s", errno, strerror(errno));continue;}inbuffer[s] = 0;//处理数据//创建套接字, 用来监听是哪一个客户端string message = inbuffer;message = func(message);//这里的处理使用一个外部的接口//处理完成后, 返回发送给客户端sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)&client, sizeof(client));}}
UdpServer析构
析构函数不解释
~UdpServer(){if (sockfd_ > 0) close(sockfd_); }
Udpclient
客户端就是给对应的服务端发送数据。 数据被服务端处理后接收即可:
#include<iostream>
#include<cstdlib>
#include<unistd.h>
using namespace std;
#include<sys/types.h>
#include<strings.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstring>
#include<string>//./udpclient serverip serverport
int main(int argc, char* argv[])
{if (argc != 3){cout << "has return" << endl;return 1;}//string serverip = argv[1];uint16_t serverprot = stoi(argv[2]);//创建套接字struct sockaddr_in server;bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(serverprot);server.sin_addr.s_addr = inet_addr(serverip.c_str());socklen_t serlen = sizeof(server);int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){cout << "socker error" << endl; return 1;}string message;char buffer[1024];while(true){ cout << "please Enter@:" << endl;getline(cin, message); //发送数据sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&server, serlen);cout << "yes" << endl;//接收数据sockaddr_in temp;socklen_t socklen;ssize_t sz = recvfrom(sockfd, (void*)buffer, sizeof(buffer) - 1, 0, (sockaddr*)&temp, &socklen); //sockfd其实就是网卡的pidif(sz > 0){buffer[sz] = 0;cout << buffer << endl;}}close(sockfd);return 0;
}
实现客户端之间的聊天功能
Udpserver
实现客户端之间的聊天可是说是在上面的代码中改两个地方。 一个是创建一个哈希表存储有多少客户端连接了服务端。 然后以后发消息就直接便利整个哈希表, 然后将数据发给每一个客户端。 如下:
#include<iostream>
using namespace std;
#include<sys/types.h>
#include<string>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<strings.h>
#include"Log.hpp"
#include<functional>
#include<netinet/in.h>
#include<unordered_map>int defaultport = 8080;
string defaultip = "0.0.0.0";//包装类要进行修改一下
using func_t = function<string(string, sockaddr_in&, unordered_map<string, sockaddr_in>&)>; Log lg;enum
{SockError = 2,BindError = 3,RecvError = 4,
};class UdpServer
{
public:UdpServer(uint16_t port = defaultport) : port_(port), ip_(defaultip), isrunning_(false){}//Init不变void Init(){//先创建套接字变量并且完成初始化。 然后就创建网卡文件sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(port_);local.sin_addr.s_addr = inet_addr(ip_.c_str());sockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){lg(Fatal, "create sock error, errno: %d, strerror: %s", errno, strerror(errno));exit(SockError);}lg(Info, "create sock success");//绑定if (bind(sockfd_, (sockaddr*)&local, sizeof(local)) < 0) {lg(Fatal, "bind error, errno: %d, strerror: %s", errno, strerror(errno));exit(BindError);}lg(Info, "bind success");}//遍历哈希表,将数据分发给所有的客户端void BroadCast(string message, unordered_map<string, sockaddr_in>& clients){cout << "1 "<< endl;for (auto& e : clients){sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)&e.second, sizeof(e.second));}cout << "2 " << endl;}void run(func_t func){isrunning_ = true;char inbuffer[1024];while (isrunning_){memset(inbuffer, 0, sizeof(inbuffer));sockaddr_in client;socklen_t client_len;memset(&client, 0, sizeof(client));//接收数据的同时监听到客户端的来源ssize_t s = recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)&client, &client_len);if (s < 0) {lg(Waring, "recvfrom error, errno: %d, strerror: %s", errno, strerror(errno));continue;}inbuffer[s] = 0;//处理数据//创建套接字, 用来监听是哪一个客户端string message = inbuffer;message = func(message, client, clients);//这里的处理使用一个外部的接口//处理完成后, 返回发送给客户端BroadCast(message, clients);}}~UdpServer(){if (sockfd_ > 0) close(sockfd_); }
private:int sockfd_;uint16_t port_;string ip_;bool isrunning_;unordered_map<string, sockaddr_in> clients; //添加哈希表};
#include"UdpServer.hpp"
#include<memory>//main.cc主要修改就是Handler函数, 我们要通过client里面的ip地址和端口号作为key,client作为value,然后放入哈希表。 同时将message处理一下,方便我们观看结果。
string Handler(string message, sockaddr_in& client, unordered_map<string, sockaddr_in>& clients)
{string tmp = inet_ntoa(client.sin_addr) + to_string(client.sin_port);if (!clients.count(tmp)){clients[tmp] = client; cout << "ip " << inet_ntoa(client.sin_addr) << " : port " << client.sin_port << " has add in talk room" << endl;}message = "[" + string(inet_ntoa(client.sin_addr)) + ":" + to_string(client.sin_port) + "]#: " + message; return message;
}// int main(int argc, char* argv[])
{if (argc != 2){cout << "has return" << endl;return 1;}//uint16_t serverport = stoi(argv[1]); unique_ptr<UdpServer> svr(new UdpServer(serverport));//svr->Init();svr->run(Handler);return 0;
}
Udpclient
#include<iostream>
using namespace std;
#include<string>
#include<sys/types.h>
#include"Log.hpp"
#include<sys/socket.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<string.h>
#include<netinet/in.h>
Log lg;class ThreadData
{
public:sockaddr_in server;int sockfd;
};//数据接收函数
void* recv_message(void* args)
{char buffer[1024];ThreadData* td = static_cast<ThreadData*>(args); while (true){//接收数据sockaddr_in temp;socklen_t len;string info;ssize_t s = recvfrom(td->sockfd, buffer, sizeof(buffer) - 1, 0, (sockaddr*)&temp, &len);if (s < 0){lg(Error, "recv error, error: %d, strerror: %s", errno, strerror(errno));continue;}buffer[s] = 0;info = buffer;cout << info << endl;}}//数据发送函数
void* send_message(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);string message;while (true){ getline(cin, message); //获取数据//发送数据sendto(td->sockfd, message.c_str(), message.size(), 0, (sockaddr*)&td->server, sizeof(td->server));}
}int main(int argc, char* argv[])
{if (argc != 3){cout << "Client server" << endl;}//先拿到套接字的参数string serverip = argv[1];uint16_t serverport = stoi(argv[2]);ThreadData td;//创建套接字与打开网卡memset(&td.server, 0, sizeof(td.server));td.server.sin_family = AF_INET;td.server.sin_port = htons(serverport);td.server.sin_addr.s_addr = inet_addr(serverip.c_str());td.sockfd = socket(AF_INET, SOCK_DGRAM, 0); //创建文件描述符, 网卡的文件描述符, 网络传输就是使用网络文件描述符找到对应的文件内的数据if (td.sockfd < 0){lg(Error, "client create sockfd error, errno: %d, strerror: %s", errno, strerror(errno));exit(1);}//创建线程, 然后运行线程, 等待线程pthread_t recv, send;pthread_create(&recv, nullptr, recv_message, &td);pthread_create(&send, nullptr, send_message, &td);pthread_join(recv, nullptr);pthread_join(send, nullptr);close(td.sockfd);return 0;
}
运行结果
最后就是运行结果, 运行结果就是下图了, 我们已经能够成功的进行两个客户端之间的远程交流
——————以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!
相关文章:

【linux网络编程】| socket套接字 | 实现UDP协议聊天室
前言:本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以, 我们主要就是要实现客户端以及服务端的逻辑代码。 那么, 接下来开始我们的学习吧。 ps:本节内容…...

第二届开放原子大赛-开源工业软件算法集成大赛即将启动!
第二届开放原子大赛-开源工业软件算法集成大赛作为开放原子开源基金会组织举办的开源技术领域专业赛事,聚焦开源底座框架平台建设,通过组件化集成的开发模式,丰富平台功能模块,拓展其应用场景,以此促进工业软件生态的繁…...

PXC集群(Percona XtraDB Cluster )
一、简介 基于Galera Cluster技术的开源分布式数据库解决方案,它允许你在多个MySQL服务器之间创建一个同步的多主复制集群。 特点: * 多主复制架构: PXC集群支持多主复制,每个节点都可以同时读写数据,这使得应用程序可以更灵活地进行负载均衡和高可用性设置。* 同步复制:…...

分布式光伏是什么意思?如何高效管理?
分布式光伏系统是指在用户现场或靠近用电现场配置较小的光伏发电供电系统,以满足特定用户的需求。根据通知,分布式光伏系统主要有以下几类定义: 10kV以下电压等级接入,且单个并网点总装机容量不超过6MW的分布式电源:这…...

提问GPT
1 理解GPT AI模型即采用深度学习技术的人工神经网络。 你不会被AI取代,而是会被熟练运用AI的人取代 1.1 问答或对话是普通用户与这一轮新AI产品的典型交互方式。 GPT生成式预训练转换器 了解当前GPT产品的形式: 通用聊天机器人…...

李飞飞团队新突破:低成本高泛化机器人训练法,零样本迁移成功率90%!
在机器人训练中,如何高效地利用模拟环境一直是研究者们关注的重点问题。 近日,美国斯坦福大学李飞飞教授团队提出了一种突破性的“数字表亲”(digital cousins)概念。这一创新方法既保留了数字孪生的优势,又大大降低了…...

PHP内存马:不死马
内存马概念 内存马是无文件攻击的一种常用手段,利用中间件的进程执行某些恶意代码。首先要讲的是PHP不死马,实质上就是直接用代码弄一个死循环,强占一个 PHP 进程,并不间断的写一个PHP shell,或者执行一段代码。 不死…...

【python】OpenCV—Connected Components
文章目录 1、任务描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数6、参考 1、任务描述 基于 python opencv 的连通分量标记和分析函数,分割车牌中的数字、号码、分隔符 cv2.connectedComponentscv2.connectedComponentsWithStatscv2.connectedComponents…...

【优选算法篇】前缀之序,后缀之章:于数列深处邂逅算法的光与影
文章目录 C 前缀和详解:基础题解与思维分析前言第一章:前缀和基础应用1.1 一维前缀和模板题解法(前缀和)图解分析C代码实现易错点提示代码解读题目解析总结 1.2 二维前缀和模板题解法(二维前缀和)图解分析C…...

win10 更新npm 和 node
win10 更新npm 和 node win10 更新 npm winR 输入cmd,打开命令行,并输入如下 # 查看当前npm版本 npm -v # 清缓存 npm cache clean --force # 强制更新npm,试过npm update -g,没起作用,版本没变化 npm install -g …...

搜索引擎算法更新对网站优化的影响与应对策略
内容概要 随着互联网的不断发展,搜索引擎算法也在不断地进行更新和优化。了解这些算法更新的背景与意义,对于网站管理者和优化人员而言,具有重要的指导意义。不仅因为算法更新可能影响到网站的排名,还因为这些变化也可能为网站带…...

使用 Q3D 计算芯片引线的 AC 和 DC R 和 L
摘要: 模具经常用于电子行业。了解其导联的寄生特性对于设计人员来说很重要。Q3D 是计算 RLCG 的完美工具。它可用于高速板或低频电力电子设备。 在下面的视频中,我们展示了如何修改几何结构、设置模型和检查结果。 详细信息: 几何图形可以在 Q3D 中创建,也可以作为不同…...

前端_008_Vite
文章目录 Vite项目结构依赖构建插件 官网:https://vitejs.cn/vite3-cn/guide/ 一句话简介:前端的一个构建工具 Vite项目结构 index.html package.json vite.config.js public目录 src目录 #新建一个vite项目 npm create vitelatest原有项目引入vite需要…...

ssm007亚盛汽车配件销售业绩管理统(论文+源码)_kaic
本科毕业设计论文 题目:亚盛汽车配件销售业绩管理系统设计与实现 系 别: XX系(全称) 专 业: 软件工程 班 级: 软件工程15201 学生姓名: 学生学号: 指导教师&am…...

如何使用python完成时间序列的数据分析?
引言 时间序列分析是统计学和数据分析中的一个重要领域,广泛应用于经济学、金融、气象学、工程等多个领域。 时间序列数据是按时间顺序排列的一系列数据点,通常用于分析数据随时间的变化趋势。 本文将介绍时间序列分析的基本概念、常用方法以及如何使用Python进行时间序列…...

数字ic设计,Windows/Linux系统,其他相关领域,软件安装包(matlab、vivado、modelsim。。。)
目录 一、总述 二、软件列表 1、modelsim_10.6c 2、notepad 3、matlab 4、Visio-Pro-2016 5、Vivado2018 6、VMware15 7、EndNote X9.3.1 8、Quartus 9、pycharm 10、CentOS7-64bit 一、总述 过往发了很多数字ic设计领域相关的内容,反响也很好。 最近…...

SD-WAN分布式组网:构建高效、灵活的企业网络架构
随着企业数字化转型的深入,分布式组网逐渐成为企业网络架构中的核心需求。无论是跨区域的分支机构互联,还是企业与云服务的连接,如何在不同区域实现高效、低延迟的网络传输,已成为业务成功的关键。SD-WAN(软件定义广域…...

Task :prepareKotlinBuildScriptModel UP-TO-DATE,编译卡在这里不动或报错
这里写自定义目录标题 原因方案其他思路 原因 一般来说,当编译到这个task之后,后续是要进行一些资源的下载的,如果你卡在这边不动的话,很有可能就是你的IDE目前没有办法进行下载。 方案 开关一下IDE内部的代理,或者…...

unseping攻防世界
源码分析 <?php highlight_file(__FILE__);//代码高亮 class ease{//声明了两个私有属性:保存要调用的方法的名称和保存该方法的参数。$method,$argsprivate $method;private $args;//构造函数在实例化类的对象时初始化,即为对象成员变量赋初始值。…...

大厂面试真题-简单描述一下SpringBoot的启动过程
SpringBoot的启动流程是一个复杂但有序的过程,它涉及多个步骤和组件的协同工作。以下是SpringBoot启动流程的详细解析: 一、启动main方法 当SpringBoot项目启动时,它会在当前工作目录下寻找有SpringBootApplication注解标识的类,…...
4. 硬件实现
博客补充: CUDA C 编程指南学习_c cuda编程-CSDN博客https://blog.csdn.net/qq_62704693/article/details/141225395?spm1001.2014.3001.5501NVIDIA GPU 架构是围绕可扩展的多线程流式多处理器 (SM) 阵列构建的。当主机 CPU 上的 CUDA 程序…...

《操作系统真象还原》第3章 完善MBR【3.1 — 3.2】
目录 引用与说明 3.1、地址、section、vstart 浅尝辄止 1、什么是地址 2、什么是 section【汇编】 3、什么是 vstart【汇编】 3.2、CPU 的实模式 1、CPU 工作原理【重要】 2、实模式下的寄存器 4、实模式下 CPU 内存寻址方式 5、栈到底是什么玩意儿 6 ~ 8 无条件转移…...

八大排序-冒泡排序
在里面找动图理解 【数据结构】八大排序(超详解附动图源码)_数据结构排序-CSDN博客 一 简介 冒泡排序应该是我们最熟悉的排序了,在C语言阶段我们就学习了冒泡排序。 他的思想也非常简单: 两两元素相比,前一个比后一个大就交换࿰…...

基于Spring Boot+Vue的助农销售平台(协同过滤算法、节流算法、支付宝沙盒支付、图形化分析)
🎈系统亮点:协同过滤算法、节流算法、支付宝沙盒支付、图形化分析; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构:B/S架构 运行环境:win10/win11、jdk17 前端&…...

uniapp写抖音小程序阻止右滑返回上一个页面
最近用uniapp写小程序遇到一个问题因为内部用到右滑的业务,但是只要右滑就会回到上一页面,用了event.preventDeafult()没有用,看了文档找到了解决办法 1.在最外层view加上touchstart事件 <view class"container" touchstart&q…...

华为配置手工负载分担模式链路聚合实验
目录 组网需求 配置思路 操作步骤 配置文件 组网图形 图1 配置手工负载分担模式链路聚合组网图 组网需求配置思路操作步骤配置文件 组网需求 如图1所示,AC1和AC2通过以太链路分别都连接VLAN10和VLAN20,且AC1和AC2之间有较大的数据流量。 用户希望A…...

【Spring】Cookie与Session
💐个人主页:初晴~ 📚相关专栏:计算机网络那些事 一、Cookie是什么? Cookie的存在主要是为了解决HTTP协议的无状态性问题,即协议本身无法记住用户之前的操作。 "⽆状态" 的含义指的是: 默认情况…...

chat_gpt回答:qt中,常见格式及格式转换
在Qt中,常见的数据格式包括: QVariant:可以存储多种数据类型,包括整型、浮点型、字符串、布尔值、日期等。QString:用于存储和处理文本字符串。QByteArray:用于处理字节数组,常用于二进制数据。…...

CSS兼容处理
“前端开发兼容——CSS篇” 在前端开发中,CSS样式的兼容性问题常常让开发者感到棘手,尤其是当涉及到IE浏览器时。由于IE浏览器版本繁多,每个版本在CSS支持上还存在差异,这导致开发者在实现统一的视觉效果时,不得不编写…...

制氮机分子筛的材质选择
制氮机分子筛的材质选择对于其性能和效率至关重要。作为制氮设备中的核心部件,分子筛承担着将空气中的氮气与氧气有效分离的重任。以下是对制氮机分子筛常用材质的详细探讨: 制氮机分子筛的主要材质 碳分子筛(CMS) 碳分子筛由活性炭经过特殊工艺加工而成…...