当前位置: 首页 > news >正文

Linux网络套接字之UDP网络程序

 (。・∀・)ノ゙嗨!你好这里是ky233的主页:这里是ky233的主页,欢迎光临~icon-default.png?t=N7T8https://blog.csdn.net/ky233?type=blog

点个关注不迷路⌯'▾'⌯

 实现一个简单的对话发消息的功能!

目录

一.新增的接口:

1.socket

2.bing

3.inet_addr

4.recvform

5.inet_ntoa

5.sendto

6.popen

二、初步代码以及结果

1.udp_server.hpp

2.udp_server.cc 

3.udp_client

4.log.hpp

5.结果 

三、爆改多线程

1.udp_client.cc

2.udp_server.cc

3.udp_server.hpp

 4.thread.hpp

5.结果


一.新增的接口:

1.socket

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>int socket(int domain, int type, int protocol);
  • 参数一:叫做域,用来判断是那个类型的,AF_UNIX, AF_LOCAL(用于本地通信)AF_INET(用于ipv4的网络通信)
  • 参数二:类型,通信的种类是什么,SOCK_DGRAM(套接字的类别,数据报的方式)
  • 参数三:协议,比如用AF_INET,SOCK_DGRAM,一般直接写0
  •  创建成功会得到一个文件描述符,失败返回-1

2.bing

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  • 参数一:创建的套接字
  • 参数二:填充sockaddr结构体
  • 参数三:所传入这个结构体对象的长度

3.inet_addr

#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>
n_addr_t inet_addr(const char *cp);
  • 将点分十进制转换成四字节,并且将主机序列转换成网络序列
  • 参数一:传入的ip

4.recvform

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
  • 用于从套接字接收数据。该函数通常与无连接的数据报服务
  • 参数一:套接字
  • 参数二和参数三:读取数据的缓冲区,用于存放读取到的数据,len叫做最终的大小
  • 参数四:读取的方式,0为阻塞的方式读取
  • 参数五和参数六:是输出型参数,我们还要知道是谁给我们发的消息

5.inet_ntoa

#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>
char *inet_ntoa(struct in_addr in);
  • 将点分四字节转换成点分十进制,并且将网络序列转换成主机序列
  • 参数一:从网络中获取到的ip

5.sendto

#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
  • 参数一:套接字
  • 参数二和参数三:要发送的数据和长度
  • 参数四:默认为0,阻塞
  • 参数五:要把数据发给谁,
  • 参数六:这个缓冲区的长度是多少

6.popen

#include <stdio.h>FILE *popen(const char *command, const char *type);

二、初步代码以及结果

1.udp_server.hpp

#ifndef _UDP_SERVER_HPP
#define _UDP_SERVER_HPP#include <iostream>
#include <string>
#include <sys/types.h>        
#include <sys/socket.h>
#include "log.hpp"
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <cstdio>
#include <unistd.h>#define SIZE 1024class UDPServer
{
public:UDPServer(uint16_t port,std::string ip=""):port_(port),ip_(ip),sock_(-1){}bool initServer(){//这里开始使用网络部分//1.创建套接字sock_=socket(AF_INET,SOCK_DGRAM,0);if(sock_<0){logMessage(FATAL,"%d:%s",errno,strerror(errno));exit(2);}//2.bind绑定:将用户设置的ip和端口号在内核中和我们的进程强关联//"192.168.1.0"->点分十进制//以.来分隔,每个区域的取值范围为0——255,//正好为1字节,四个区域理论上需要四字节//所以我们的看的时候会由4字节显示,转换为点分十进制//初始化结构体完成struct sockaddr_in local;bzero(&local,sizeof(local));//填充结构体local.sin_family=AF_INET;//服务器的IP和端口号,未来也是要发送给对方主机才能互相通信的//所以要先把数据发送到网络,要用htonslocal.sin_port=htons(port_);//同上要先把点分十进制转换成四字节ip//还需要要把四字节主机序列,转换成网络序列//所以用inet_addr一次性转成网络四字节序列//local.sin_addr.s_addr=inet_addr(ip_.c_str());//一般情况下,只要是这个端口的,那么我们就直接全部都接受,而不是指定端口local.sin_addr.s_addr = ip_.empty() ? INADDR_ANY : inet_addr(ip_.c_str());//这里需要做强转,因为bind需要的是sockaddr类型而不是sockaddr_in类型if(bind(sock_,(struct sockaddr*)&local,sizeof(local))<0){logMessage(FATAL,"%d:%s",errno,strerror(errno));exit(2);}//至此初始化服务器写完,首先创建套接字,接着用bind来绑定ip和端口号写进内核中logMessage(NORMAL, "init udp server done ... %s", strerror(errno));return true;}void strat(){//作为一款网络服务器,是永远不退出的!// 服务器启动-> 进程 -> 常驻进程 -> 永远在内存中存在,除非挂了!//echo服务器,主机给我们发送消息,我们原封不动的返回char buffer[SIZE];for( ; ;){//1.读取数据//注意peer,纯输出型参数struct sockaddr_in peer;bzero(&peer,sizeof(peer));//输入:peer 缓冲区大小//输入:实际读到的peer大小//所以len的大小要为实际的peer大小socklen_t len = sizeof(peer);//这样就把数据读取到buffer里了ssize_t s= recvfrom(sock_,&buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);if(s>0){buffer[s]=0;//我们目前数据当作字符串//1.输出发送的数据信息//2.是谁?提取!uint16_t cil_port=ntohs(peer.sin_port);//从网络中来的,所以要进行转成主机端口号std::string cli_p=inet_ntoa(peer.sin_addr);//将点分四字节转换成点分十进制,并且将网络序列转换成主机序列printf("[%s:%d]# %s\n",cli_p.c_str(),cil_port,buffer);}//2.分析和处理数据//3.写回数据sendto(sock_,buffer,sizeof(buffer),0,(struct sockaddr*)&peer,len);}}~UDPServer(){if(sock_>=0){close(sock_);}}private:
uint16_t port_;
std::string ip_;
int sock_;
};#endif

2.udp_server.cc 

#include "udp_server.hpp"
#include <memory>
#include <cstdlib>static void usage(std::string proc)
{std::cout << "\nUsage: " << proc << " port\n" << std::endl;
}int main(int argc,char *argv[])
{//检查传入ip和端口号是否错误if(argc!=2){usage(argv[0]);exit(1);}//初始化服务器,利用unique_ptruint16_t port=atoi(argv[1]);//std::string ip=argv[1];std::unique_ptr<UDPServer> svr(new UDPServer(port));svr->initServer();svr->strat();return 0;
}

3.udp_client

#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <memory>
#include "thread.hpp"static void usage(std::string proc)
{std::cout << "\nUsage: " << proc << " serverIp serverPort\n"<< std::endl;
}int main(int argc, char *argv[])
{if (argc != 3){usage(argv[0]);exit(1);}int sock = socket(AF_INET, SOCK_DGRAM, 0);if (sock < 0){std::cerr << "socket error" << std::endl;exit(2);}//client要不要bind?要bind,但是client不会显示的bind,程序员不会自己bind//client是一个客户端,是普通人下载并使用的//如果需要显示的bind,也就要求了客户端也bind了一个固定的端口//万一其他的客户端提前真用了端口号了呢,这时这个客户端就无法启动了//所以不用显示的bind指定端口号,直接让OS自动随机选择std::string message;//给谁发的信息如下struct sockaddr_in server;memset(&server,0,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(atoi(argv[2]));server.sin_addr.s_addr=inet_addr(argv[1]);char buffer[1024];while(1){std::cout<<"请输入你的信息# ";std::getline(std::cin,message);if(message=="quit"){break;}//当client首次发送消息给服务器的时候,OS会自动给client bind它的ip和portsendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));//至此客户端和服务器已经建成//这里需要定义两个占位的struct sockaddr_in temp;socklen_t len = sizeof(temp);ssize_t s= recvfrom(sock,&buffer,sizeof(buffer)-1,0,(struct sockaddr*)&temp,&len);if(s>0){buffer[s]=0;std::cout<<"server echo# "<<buffer<<std::endl;}}close(sock);return 0;
}

4.log.hpp

#pragma once#include <iostream>
#include <cstdio>
#include <cstdarg>
#include <ctime>
#include <string>// 日志是有日志级别的
#define DEBUG   0
#define NORMAL  1
#define WARNING 2
#define ERROR   3
#define FATAL   4const char *gLevelMap[] = {"DEBUG","NORMAL","WARNING","ERROR","FATAL"
};#define LOGFILE "./threadpool.log"// 完整的日志功能,至少: 日志等级 时间 支持用户自定义(日志内容, 文件行,文件名)
void logMessage(int level, const char *format, ...)
{
#ifndef DEBUG_SHOWif(level== DEBUG) return;
#endif// va_list ap;// va_start(ap, format);// while()// int x = va_arg(ap, int);// va_end(ap); //ap=nullptrchar stdBuffer[1024]; //标准部分time_t timestamp = time(nullptr);// struct tm *localtime = localtime(&timestamp);snprintf(stdBuffer, sizeof stdBuffer, "[%s] [%ld] ", gLevelMap[level], timestamp);char logBuffer[1024]; //自定义部分va_list args;va_start(args, format);// vprintf(format, args);vsnprintf(logBuffer, sizeof logBuffer, format, args);va_end(args);//FILE *fp = fopen(LOGFILE, "a");printf("%s%s\n", stdBuffer, logBuffer);//fprintf(fp, "%s%s\n", stdBuffer, logBuffer);//fclose(fp);
}

5.结果 

这个叫做本地环回:client和server发送数据只在本地协议栈中进行数据流动,不会把我们的数据发送到网络中,通常用于本地网络服务器的测试

 ——————————————————————————————————————————

其中客户端时OS随机绑定的,全0IP是因为只要是这个端口的我都要,不要具体IP的

三、爆改多线程

我们要把这个代码改成一个类似QQ群一样的模式,所有人发的消息都可以看到

1.udp_client.cc

#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <memory>
#include "thread.hpp"uint16_t serverport=0;
std::string serverip;//发现:无论是多线程读还是写,用的sock都是一个,sock代表就是文件,UDP是全双工的-> 可以同时进行收发而不受干扰static void usage(std::string proc)
{std::cout << "\nUsage: " << proc << " serverIp serverPort\n"<< std::endl;
}//发送逻辑的回调
static void *udpSend(void *args)
{//根据线程的封装,先转换成data*的然后获取里面的args_,然后在转会int*//获得一个指针指向args里面的sock,然后解引用int sock=*(int*)((ThreadData*)args)->args_;std::string name = ((ThreadData*)args)->name_;//下面逻辑与之前一样,构建发送的字符串,套接字信息std::string message;//给谁发的信息如下struct sockaddr_in server;memset(&server,0,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(serverport);server.sin_addr.s_addr=inet_addr(serverip.c_str());//开始不间断的发送while(1){std::cerr<<"请输入你的信息# ";std::getline(std::cin,message);if(message=="quit"){break;}//当client首次发送消息给服务器的时候,OS会自动给client bind它的ip和portsendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));//至此客户端和服务器已经建成}return nullptr;
}//接受逻辑的回调
static void *udpRecv(void *args)
{int sock=*(int*)((ThreadData*)args)->args_;std::string name = ((ThreadData*)args)->name_;//需要不断地去读,要去指定的套接字中读取while(1){char buffer[1024];struct sockaddr_in temp;socklen_t len = sizeof(temp);ssize_t s= recvfrom(sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&temp,&len);if(s>0){buffer[s]=0;std::cout<<buffer<<std::endl;}}
}int main(int argc, char *argv[])
{if (argc != 3){usage(argv[0]);exit(1);}int sock = socket(AF_INET, SOCK_DGRAM, 0);if (sock < 0){std::cerr << "socket error" << std::endl;exit(2);}serverport=atoi(argv[2]);serverip=argv[1];//client要不要bind?要bind,但是client不会显示的bind,程序员不会自己bind//client是一个客户端,是普通人下载并使用的//如果需要显示的bind,也就要求了客户端也bind了一个固定的端口//万一其他的客户端提前真用了端口号了呢,这时这个客户端就无法启动了//所以不用显示的bind指定端口号,直接让OS自动随机选择//爆改多线程,一个线程发送数据到各个主机,一个线程接受各个数据。std::unique_ptr<Thread> sender(new Thread(1,udpSend,(void*)&sock));std::unique_ptr<Thread> recver(new Thread(2,udpRecv,(void*)&sock));sender->start();recver->start();sender->join();recver->join();close(sock);// std::string message;// //给谁发的信息如下// struct sockaddr_in server;// memset(&server,0,sizeof(server));// server.sin_family=AF_INET;// server.sin_port=htons(atoi(argv[2]));// server.sin_addr.s_addr=inet_addr(argv[1]);// char buffer[1024];// while(1)// {//     std::cout<<"请输入你的信息# ";//     std::getline(std::cin,message);//     if(message=="quit")//     {//         break;//     }//     //当client首次发送消息给服务器的时候,OS会自动给client bind它的ip和port//     sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));//     //至此客户端和服务器已经建成//     //这里需要定义两个占位的//     struct sockaddr_in temp;//     socklen_t len = sizeof(temp);//     ssize_t s= recvfrom(sock,&buffer,sizeof(buffer)-1,0,(struct sockaddr*)&temp,&len);//     if(s>0)//     {//         buffer[s]=0;//         std::cout<<"server echo# "<<buffer<<std::endl;//     }// }// close(sock);return 0;
}

2.udp_server.cc

#include "udp_server.hpp"
#include <memory>
#include <cstdlib>static void usage(std::string proc)
{std::cout << "\nUsage: " << proc << " port\n" << std::endl;
}int main(int argc,char *argv[])
{//检查传入ip和端口号是否错误if(argc!=2){usage(argv[0]);exit(1);}//初始化服务器,利用unique_ptruint16_t port=atoi(argv[1]);//std::string ip=argv[1];std::unique_ptr<UDPServer> svr(new UDPServer(port));svr->initServer();svr->strat();return 0;
}

3.udp_server.hpp

#ifndef _UDP_SERVER_HPP
#define _UDP_SERVER_HPP#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include "log.hpp"
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <cstdio>
#include <unistd.h>
#include <unordered_map>#define SIZE 1024class UDPServer
{
public:UDPServer(uint16_t port, std::string ip = ""): port_(port), ip_(ip), sock_(-1){}bool initServer(){// 这里开始使用网络部分// 1.创建套接字sock_ = socket(AF_INET, SOCK_DGRAM, 0);if (sock_ < 0){logMessage(FATAL, "%d:%s", errno, strerror(errno));exit(2);}// 2.bind绑定:将用户设置的ip和端口号在内核中和我们的进程强关联//"192.168.1.0"->点分十进制// 以.来分隔,每个区域的取值范围为0——255,// 正好为1字节,四个区域理论上需要四字节// 所以我们的看的时候会由4字节显示,转换为点分十进制// 初始化结构体完成struct sockaddr_in local;bzero(&local, sizeof(local));// 填充结构体local.sin_family = AF_INET;// 服务器的IP和端口号,未来也是要发送给对方主机才能互相通信的// 所以要先把数据发送到网络,要用htonslocal.sin_port = htons(port_);// 同上要先把点分十进制转换成四字节ip// 还需要要把四字节主机序列,转换成网络序列// 所以用inet_addr一次性转成网络四字节序列// local.sin_addr.s_addr=inet_addr(ip_.c_str());// 一般情况下,只要是这个端口的,那么我们就直接全部都接受,而不是指定端口local.sin_addr.s_addr = ip_.empty() ? INADDR_ANY : inet_addr(ip_.c_str());// 这里需要做强转,因为bind需要的是sockaddr类型而不是sockaddr_in类型if (bind(sock_, (struct sockaddr *)&local, sizeof(local)) < 0){logMessage(FATAL, "%d:%s", errno, strerror(errno));exit(2);}// 至此初始化服务器写完,首先创建套接字,接着用bind来绑定ip和端口号写进内核中logMessage(NORMAL, "init udp server done ... %s", strerror(errno));return true;}void strat(){// 作为一款网络服务器,是永远不退出的!//  服务器启动-> 进程 -> 常驻进程 -> 永远在内存中存在,除非挂了!// echo服务器,主机给我们发送消息,我们原封不动的返回char buffer[SIZE];for (;;){// 1.读取数据// 注意peer,纯输出型参数struct sockaddr_in peer;bzero(&peer, sizeof(peer));// 输入:peer 缓冲区大小// 输入:实际读到的peer大小// 所以len的大小要为实际的peer大小socklen_t len = sizeof(peer);// 这样就把数据读取到buffer里了ssize_t s = recvfrom(sock_, &buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);char result[256];char key[64];std::string cmd_echo;if (s > 0){buffer[s] = 0; // 我们目前数据当作字符串// 1.输出发送的数据信息// 2.是谁?提取!// if(strcasestr(buffer,"rm")!=nullptr||strcasestr(buffer,"rmdir")!=nullptr)// {//     std::string err_message="坏人";//     std::cout<<err_message<<buffer<<std::endl;//     sendto(sock_, err_message.c_str(), err_message.size(), 0, (struct sockaddr *)&peer, len);//     continue;// }// FILE *fp = popen(buffer, "r");// if (nullptr == fp)// {//     logMessage(ERROR, "%d:%s", errno, strerror(errno));//     continue;// }// while (fgets(result, sizeof(result), fp) != nullptr)// {//     cmd_echo += result;// }// fclose(fp);uint16_t cil_port = ntohs(peer.sin_port);     // 从网络中来的,所以要进行转成主机端口号std::string cil_ip = inet_ntoa(peer.sin_addr); // 将点分四字节转换成点分十进制,并且将网络序列转换成主机序列// printf("[%s:%d]# %s\n",cli_p.c_str(),cil_port,buffer);snprintf(key, sizeof(key), "%s-%d", cil_ip.c_str(), cil_port);logMessage(NORMAL,"key: %s",key);auto it = users_.find(key);if(it==users_.end()){logMessage(NORMAL,"add new user:%s",key);users_.insert({key,peer});}}// 2.分析和处理数据// 3.写回数据// sendto(sock_,buffer,sizeof(buffer),0,(struct sockaddr*)&peer,len);//sendto(sock_, cmd_echo.c_str(), cmd_echo.size(), 0, (struct sockaddr *)&peer, len);for(auto &iter:users_){std::string sendMessage=key;sendMessage+="# ";sendMessage+=buffer;logMessage(NORMAL,"push message to %s",iter.first.c_str());sendto(sock_, sendMessage.c_str(), sendMessage.size(), 0, (struct sockaddr *)&(iter.second), sizeof(iter.second));}}}~UDPServer(){if (sock_ >= 0){close(sock_);}}private:uint16_t port_;std::string ip_;int sock_;std::unordered_map<std::string, struct sockaddr_in> users_;
};#endif

 4.thread.hpp

#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <cstdio>using namespace std;typedef void*(*fun_t)(void*);class ThreadData
{
public:void* args_;string name_;
};class Thread
{
public:Thread(int num,fun_t callback,void* args):func_(callback){char namebuffer[64];snprintf(namebuffer,sizeof(namebuffer),"Thread-%d",num);name_=namebuffer;tdata_.args_=args;tdata_.name_=name_;}void start(){pthread_create(&tid_,nullptr,func_,&tdata_.args_);}void join(){pthread_join(tid_,nullptr);}string name(){return name_;}~Thread(){}private:string name_;fun_t func_;ThreadData tdata_;pthread_t tid_;
};

5.结果

利用管道可以更好的观看

相关文章:

Linux网络套接字之UDP网络程序

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 实现一个简单的对话发消息的功能&#xff01; 目录…...

Apache POI 解析和处理Excel

摘要&#xff1a;由于开发需要批量导入Excel中的数据&#xff0c;使用了Apache POI库&#xff0c;记录下使用过程 1. 背景 Java 中操作 Excel 文件的库常用的有Apache POI 和阿里巴巴的 EasyExcel 。Apache POI 是一个功能比较全面的 Java 库&#xff0c;适合处理复杂的 Offi…...

SQL 注入攻击 - insert注入

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、注入原理 描述:insert注入是指通过前端注册的信息被后台通过insert操作插入到数据库中。如果后台没有做相应的处理,就可能导致insert注入漏洞。原因:后台未对用户输入进行充…...

第一个 Angular 项目 - 添加路由

第一个 Angular 项目 - 添加路由 前置项目是 第一个 Angular 项目 - 添加服务&#xff0c;之前的切换页面使用的是 ngIf 对渲染的组件进行判断&#xff0c;从而完成渲染。这一步的打算是添加路由&#xff0c;同时添加 edit recipe 的功能(同样通过路由实现) 用到的内容为&…...

如何简洁高效的搭建一个SpringCloud2023的maven工程

前言 依赖管理有gradle和maven&#xff0c;在这里选择比较常用和方便的Maven作为工程项目和依赖管理工具来搭建SpringCloud实战工程。主要用到的maven管理方式是多模块和bom依赖管理。 什么是maven的多模块依赖管理 Maven 多模块项目相对于单模块项目而言&#xff0c;依赖是…...

uniapp直接连接wifi(含有ios和安卓的注意事项)

前言 小程序中直接连接wifi-----微信小程序 代码 启动 //启动wifistartWifi() {return new Promise((resolve, reject) > {uni.startWifi({success: (res) > {console.log(启动wifi 成功, res)resolve(true)},fail: (err) > {console.error(启动wifi 失败, err)uni.s…...

一. Ubuntu入门

目录 一. Ubuntu系统安装 1. 安装虚拟机软件VMware 2. 安装Ubuntu操作系统 二. Ubuntu系统入门 1. Shell操作 1.1 Shell 简介 1.2 Shell基本操作 1.3 常用Shell命令 (1) 目录信息查看命令ls (2) 目录切换命令cd (3) 当前路径显示命令pwd (4) 系统信息查看命令uname…...

rk3568 Android12 增加支持 ntfs 格式

rk3568 Android12 增加支持 ntfs 格式 Windows平台上可移动硬盘支持 NTFS,FAT32,exFAT三种格式。Fat32文件格式是一种通用格式,任何USB存储设备都会预装该文件系统,可以在任何操作系统平台上使用。最主要的缺陷是只支持最大单文件大小容量为4GB,因此日常使用没有问题,只有…...

【MapReduce】02.Hadoop序列化

实现bean对象序列化步骤 自定义bean对象实现序列化接口。 1&#xff09;必须实现Writable接口 2&#xff09;反序列化时&#xff0c;需要反射调用空参构造函数&#xff0c;所以必须有空参构造 public FlowBean(){super(); } 3&#xff09;重写序列化方法 Override public …...

【Claude 3】一文谈谈Anthropic(Claude) 亚马逊云科技(Bedrock)的因缘际会

文章目录 前言1. Anthropic的诞生2. Anthropic的“代表作”——Claude 3的“三驾马车”3. 亚马逊云科技介绍4. 强大的全托管服务平台——Amazon Bedrock5. 亚马逊云科技(AWS)和Anthropic的联系6. Claude 3模型与Bedrock托管平台的关系7. Clude 3限时体验入口分享【⚠️截止3月1…...

c#开发100问?

什么是C#&#xff1f;C#是由谁开发的&#xff1f;C#与Java之间有哪些相似之处&#xff1f;C#与C有哪些不同之处&#xff1f;C#的主要特性是什么&#xff1f;请解释C#中的类和对象。C#中的命名空间是什么&#xff1f;什么是C#中的属性和字段&#xff1f;请解释C#中的继承和多态性…...

回归预测 | Matlab实现BiTCN-BiGRU-Attention双向时间卷积双向门控循环单元融合注意力机制多变量回归预测

回归预测 | Matlab实现BiTCN-BiGRU-Attention双向时间卷积双向门控循环单元融合注意力机制多变量回归预测 目录 回归预测 | Matlab实现BiTCN-BiGRU-Attention双向时间卷积双向门控循环单元融合注意力机制多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.M…...

SpringCloud微服务-RabbitMQ快速入门

文章目录 RabbitMQ快速入门1、什么是MQ&#xff1f;2、RabbitMQ概述3、RabbitMQ的结构和概念4、常见消息模型5、HelloWorld RabbitMQ快速入门 1、什么是MQ&#xff1f; MQ &#xff08;MessageQueue&#xff09;&#xff0c;中文是消息队列&#xff0c;字面来看就是存放消息的…...

OpenCV学习笔记(五)——图片的缩放、旋转、平移、裁剪以及翻转操作

目录 图像的缩放 图像的平移 图像的旋转 图像的裁剪 图像的翻转 图像的缩放 OpenCV中使用cv2.resize()函数进行缩放&#xff0c;格式为&#xff1a; resize_imagecv2.resize(image,(new_w,new_h),插值选项) 其中image代表的是需要缩放的对象&#xff0c;(new_w,new_h)表…...

c++ 串口通信库

根据资料整理的串口通信库&#xff0c;封装成为了动态库&#xff0c;使用者只需要调用接口即可 使用实例如下&#xff1a; //接受数据 void CSerialPortCommonLibDemoDlg::OnReceive() { char * str NULL; str new char[256]; _port.readAllData(str); CString s…...

数据结构之单链表及其实现!

目录 ​编辑 1. 顺序表的问题及思考 2.链表的概念结构和分类 2.1 概念及结构 2.2 分类 3. 单链表的实现 3.1 新节点的创建 3.2 打印单链表 3.3 头插 3.4 头删 3.5 尾插 3.6 尾删 3.7 查找元素X 3.8 在pos位置修改 3.9 在任意位置之前插入 3.10 在任意位置删除…...

Ubuntu 22.04修改静态ip

1. 备份原网络配置文件 # 配置文件名称因机器设置有异 cd /etc/netplan cp 01-network-config.yaml 01-network-config.yaml.bak# 文件内容如下 network:version: 2renderer: NetworkManager2. 修改配置文件 使用 ipconfig 命令查看网络信息&#xff0c;ip addr 命令也可 我这…...

kali当中不同的python版本切换(超简单)

kali当中本身就是自带两个python版本的 配置 update-alternatives --install /usr/bin/python python /usr/bin/python2 100 update-alternatives --install /usr/bin/python python /usr/bin/python3 150 切换版本 update-alternatives --config python 0 1 2编号选择一个即可…...

MongoDB聚合运算符;$dateToString

$dateToString聚合运算符按用户指定的格式将日期对象转为字符串。 语法 { $dateToString: {date: <dateExpression>,format: <formatString>,timezone: <tzExpression>,onNull: <expression> } }字段说明&#xff1a; 字段是否必须描述date是<da…...

【开源】SpringBoot框架开发教学资源共享平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 类图设计3.3 数据库设计3.3.1 课程档案表3.3.2 课程资源表3.3.3 课程作业表3.3.4 课程评价表 四、系统展…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...