网络编程(一)网络编程入门
本节课学习TCP客户端和服务器端编程架构,其分为分为C/S(客户端/服务器模式)和B/S(浏览器/服务器架构模式)两种模式。接下来我们分别了解这两种模式
C/S模式
C/S模式:服务器首先先启动,并根据客户端请求做出相应的响应。
服务器:
1.打开一个通信通道,在某一端口接受客户端请求。
2.接受到客户端请求后处理请求并返回信息给客户端。
3.继续等待客户端请求直到关闭服务器。
客户端:
1.打开一个通信通道,并连接到服务器所在主机的特定端口。
2.向服务器发送请求,等待并接收响应,继续发送请求。
3.关闭客户端。
B/S模式
B/S模式:浏览器是客户端的主要应用软件,主要事物逻辑在服务器实现,前端(浏览器)负责展示。
WinSocket
Windows Sockets 规范是一套开放的、支持多协议的Windows下的网络编程接口。目前实际应用中的Windwos Sockets规范主要有1.1版本和2.2版本,其中1.1版本只支持TCP/IP协议,而2.2支持多协议,并具有良好的向后兼容性。这俩版本对应的头文件分别是:WinSocket.h WinSocket2.h
Socket传输
socket通常被称作套接字,是网络通信的编程接口,本质是操作系统提供的双向通信端点。客户端去连接服务器端,需要一对套接字,一个运行在服务器端,一个运行在客户端。套接字处于网络协议的传输层,用于实现服务器和客户端之间的物理连接,并进行数据传输。传输层主要有UDP和TCP两个协议:
TCP协议:TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。 一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂
UDP协议:UDP是一个非连接的协议,传输数据之前源端和终端不建立连接, 当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。 在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、 计算机的能力和传输带宽的限制; 在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段
工作原理如下:
服务器端:创建套接字 → 绑定IP和端口 → 监听连接 → 接受客户端请求 → 数据传输 → 关闭连接
客户端:创建套接字 → 连接服务器 → 数据传输 → 关闭连接
相关背景知识
字节序:字节与存储位置的关系
小端:将低序字节存储在起始地址
大端:将高序字节存储在起始地址
网络字节序:网络上的字节序
代码实现
接下来我们将通过代码实现一个简单TCP/IP服务器和客户端的一般模型
服务端代码实现
服务端的实现有以下几个步骤:
1. 初始化Winsock
WORD wsVersion = MAKEWORD(2, 2);
WSADATA wsaData = {0};
WSAStartup(wsVersion, &wsaData);
2. 创建套接字
//创建套接字需要使用函数socket(),其语法如下:
SOCKET socket
(int af, // 地址族规范:常见有IPv6(AF_INET6)或IPv4(AF_INET)int type, // 套接字类型:原始套接字SOCKET_RAW(对较低层次的协议直接访问,例如IP、ICMP协议)、SOCK_STREAM面向连接(TCP/IP协议)、SOCK_DGRAM面向无连接(UDP协议)int protocol // 使用的协议:这里我们可以直接写0,这样操作系统就会根据前面两个选项推断出你想用的协议
);//实现代码
SOCKET sSocket = socket(AF_INET, SOCK_STREAM, 0);
3. 绑定套接字
//绑定套接字,需要使用函数bind,其语法如下:
int bind
(SOCKET s, // 套接字:将创建的套接字变量名字写上去const struct sockaddr FAR *name, // 网络地址信息:包含通信所需要的相关信息,传递的是一个sockaddr结构体,在具体传参的时候,会用该结构体的变体sockaddr_in形式去初始化相关字段int namelen // sockaddr_in结构体的长度
);//其中sockaddr_in结构体的定义如下:
struct sockaddr_in
{short sin_family; // 地址族规范:与创建套接字时候所使用的一致即可u_short sin_port; // 端口struct in_addr sin_addr; // IP地址char sin_zero[8]; // 无特殊的含义,只是为了与sockaddr结构体一致,因为在给套接字分配网络地址的时候会调用bind函数,其中的参数会把sockaddr_in结构体转化为sockaddr结构体
};//其中in_addr结构体的定义如下:
struct in_addr
{union {struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { u_short s_w1,s_w2; } S_un_w;u_long S_addr;} S_un;#define s_addr S_un.S_addr/* can be used for most tcp & ip code */#define s_host S_un.S_un_b.s_b2/* host on imp */#define s_net S_un.S_un_b.s_b1/* network */#define s_imp S_un.S_un_w.s_w2/* imp */#define s_impno S_un.S_un_b.s_b4/* imp # */#define s_lh S_un.S_un_b.s_b3/* logical host */
};//网络地址是一个u_long类型的地址,因此我们可以使用函数inet_addr将字符串按照网络字节序进行转换
inet_addr("192.168.1.1");//代码实现
sockaddr_in sockAddrInfo = {0}; // 初始化
sockAddrInfo.sin_addr.S_un.S_addr = inet_addr("192.168.1.1"); // 地址
sockAddrInfo.sin_port = htons(2118); // 端口需要按照网络字节序,所以需要使用htons函数
sockAddrInfo.sin_family = AF_INET; // 地址族规范
bind(sSocket, (sockaddr*)&sockAddrInfo, sizeof(sockAddrInfo));
4. 监听套接字
//监听套接字,使用函数listen,其语法如下:
int listen
(SOCKET s, // 套接字:将创建的套接字变量名字写上去int backlog // 待处理连接队列的最大长度:表示队列中最多同时有多少个连接请求
);// 实现代码
listen(sSocket, 1);
5. 等待客户端连接
//等待连接,使用函数accept,其语法如下:
SOCKET accept
(SOCKET s, // 套接字:将创建的套接字变量名字写上去struct sockaddr FAR *addr, // 输出参数,需要传入一个sockaddr结构体的地址int FAR *addrlen // 输出参数,需要传入一个sockaddr结构体长度的地址
);//实现代码,accept返回的也是一个SOCKET
sockaddr_in acceptSockAddrInfo = {0}; // 初始化
int acceptSockAddrLen = 0;
SOCKET aSocket = accept(sSocket, (sockaddr*)&acceptSockAddrInfo, &acceptSockAddrLen);
6. 接收和发送数据
//接收数据使用函数recv,其语法如下:
int recv
(SOCKET s, // 套接字:将accept返回的套接字变量名字写上去char FAR *buf, // 输出参数,数据缓冲区,接收到的数据int len, // 缓冲区大小int flags // 指定调用方式的标志,这个我们就直接写0即可
);//实现代码
char buf[100] = {0};
recv(aSocket, buf, 100, 0);
printf("Recv data: %s\n", buf);//发送数据使用函数send,其语法如下:int send
(SOCKET s, // 套接字:将accept返回的套接字变量名字写上去const char FAR *buf, // 传输数据的缓冲区int len, // 缓冲区大小int flags // 指定调用方式的标志,这个我们就直接写0即可
);//实现代码
send(aSocket, buf, strlen(buf)+1, 0);
7. 被动断开连接
//断开连接使用shutdown函数,其语法如下:
int shutdown
(SOCKET s, // 套接字:将accept返回的套接字变量名字写上去int how // 断开连接的形式:SD_SEND不再发送数据、SD_RECEIVE不再接受数据、SD_BOTH不再收发数据
);// 实现代码
shutdown(aSocket, SD_SEND);
8.关闭套接字
//关闭2个套接字=使用函数closesocket,其语法如下:
int closesocket
(SOCKET s // 套接字:将accept返回的套接字变量名字写上去
);// 实现代码
closesocket(aSocket);
closesocket(sSocket);
完整代码如下:
#include<WinSock2.h>//Winsock2头文件需置于Windows.h之前,避免旧版Winsock1.1头文件冲突
#include<Windows.h>
#include<iostream>
#include<WS2tcpip.h>#pragma comment(lib,"ws2_32.lib")//显式链接Winsock2库ws2_32.libint main(int argc, char* argv[])
{// 1. 初始化WinsockWORD wsVersion = MAKEWORD(2, 2);WSADATA wsaData = {0};WSAStartup(wsVersion, &wsaData);// 2. 创建套接字SOCKET sSocket = socket(AF_INET, SOCK_STREAM, 0);if (SOCKET_ERROR == sSocket) {printf("套接字闯创建失败!\n" );}else {printf("套接字闯创建成功!\n" );}3. 绑定套接字sockaddr_in sockAddrInfo = {0}; // 初始化sockAddrInfo.sin_addr.S_un.S_addr = inet_addr("172.16.176.5");sockAddrInfo.sin_port = htons(2118); // 端口sockAddrInfo.sin_family = AF_INET; // 地址族规范int bRes = bind(sSocket, (sockaddr*)&sockAddrInfo, sizeof(sockAddrInfo));if (SOCKET_ERROR == bRes) {printf("绑定失败!\n");}else {printf("绑定成功!\n");}// 3. 监听套接字int lRes = listen(sSocket, 1);if (SOCKET_ERROR == lRes) {printf("监听失败!\n");}else {printf("监听成功!\n");}4. 监听套接字sockaddr_in acceptSockAddrInfo = {0}; // 初始化int acceptSockAddrLen = sizeof(acceptSockAddrInfo);5. 等待客户端连接SOCKET aSocket = accept(sSocket, (sockaddr*)&acceptSockAddrInfo, &acceptSockAddrLen);if (INVALID_SOCKET == aSocket) {printf("服务端等待连接失败!\n");}else {printf("服务端等待连接成功!\n");}6. 接收和发送数据char buf[100] = {0};// 循环while (true) {int ret = recv(aSocket, buf, 100, 0);if (ret == 0) {// 如果recv返回为0则表示客户端要断开连接,就跳出循环断开连接break;}printf("Recv data: %s\n", buf);send(aSocket, buf, strlen(buf)+1, 0);memset(buf, 0, 100);}// 7. 断开连接shutdown(aSocket, SD_SEND);// 8.关闭套接字closesocket(aSocket);closesocket(sSocket);// 9. 释放 Winsock 库资源 WSACleanup();return 0;
}
客户端代码实现
客户端的实现有以下几个步骤:
1. 初始化Winsock
2. 创建套接字
3. 绑定套接字
4. 连接服务器
5. 发送和接收数据
6. 主动断开连接
7. 关闭套接字
#include<WinSock2.h>
#include<Windows.h>
#include<iostream>
#include<WS2tcpip.h>#pragma comment(lib,"ws2_32.lib")int main()
{// 1. 初始化WinsockWORD wsVersion = MAKEWORD(2, 2);WSADATA wsaData = {0};WSAStartup(wsVersion, &wsaData);// 2. 创建套接字SOCKET cSocket = socket(AF_INET, SOCK_STREAM, 0);if (SOCKET_ERROR == cSocket) {printf("套接字闯创建失败!\n");}else {printf("套接字闯创建成功!\n");}// 3. 绑定套接字sockaddr_in sockAddrInfo = {0}; // 初始化sockAddrInfo.sin_addr.S_un.S_addr = inet_addr("172.16.176.12");sockAddrInfo.sin_port = htons(2119); // 端口sockAddrInfo.sin_family = AF_INET; // 地址族规范int bRes = bind(cSocket, (sockaddr*)&sockAddrInfo, sizeof(sockAddrInfo));if (SOCKET_ERROR == bRes) {printf("绑定失败!\n");}else {printf("绑定成功!\n");}// 4. 连接服务器sockaddr_in serverSockAddrInfo = {0}; // 初始化serverSockAddrInfo.sin_addr.S_un.S_addr = inet_addr("172.16.176.5");serverSockAddrInfo.sin_port = htons(2118); // 端口serverSockAddrInfo.sin_family = AF_INET; // 地址族规范int cRes = connect(cSocket, (sockaddr*)&serverSockAddrInfo, sizeof(serverSockAddrInfo));if (SOCKET_ERROR == cRes) {printf("与服务器连接失败!\n");}else {printf("与服务器连接成功!\n");}// 5. 发送和接收数据printf("Input: ");char sendData[100];scanf("%s", sendData);send(cSocket, sendData, strlen(sendData)+1, 0);char buf[100] = {0};recv(cSocket, buf, 100, 0);printf("Recv data: %s \n", buf);// 6. 主动断开连接shutdown(cSocket, SD_SEND);// 7. 关闭套接字closesocket(cSocket);WSACleanup();return 0;
}
多人聊天功能
在多人聊天中,有多个客户端对应一个服务器端。当某客户端发送消息时,由服务器端接收消息并转发给其他客户端
服务器端
#include<WinSock2.h>
#include<Windows.h>
#include<iostream>
#include<WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include<vector>using std::vector;
vector<SOCKET> clientList;//用于存储多个客户端DWORD WINAPI revcMeesage(LPVOID param)
{SOCKET client = (SOCKET)param;char buff[0x100]{ 0 };int recvSize = 0;while ((recvSize=recv(client, buff,0x100,0))>0){for (int i=0;i<clientList.size();i++){if (clientList[i]!= client){send(clientList[i],buff, recvSize,0);//服务器发送给其他客户端}}}for (int i = 0; i < clientList.size(); i++){if (clientList[i] == client){closesocket(clientList[i]);clientList.erase(clientList.begin()+i);printf("客户端%u断开了连接!\n");}}return 0;
}
int main()
{//1.初始化网络环境WSADATA data{ 0 };WSAStartup(MAKEWORD(2, 2), &data);//2.创建SOCKETSOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//3绑定端口号IP地址sockaddr_in serverAddr{ 0 };serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(8888);inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);bind(server, (SOCKADDR*)&serverAddr, sizeof(serverAddr));//4.监听listen(server, SOMAXCONN);//5.接受会话sockaddr_in clientAddr{ 0 };int size = sizeof(clientAddr);while (1){SOCKET client = accept(server, (SOCKADDR*)&clientAddr, &size);clientList.push_back(client);CreateThread(NULL,NULL, revcMeesage, (LPVOID)client,NULL,NULL);printf("客户端%u连接到了服务器\n", client);}closesocket(server);return 0;
}
客户端
#include<Windows.h>
#include<iostream>
#include<WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
DWORD WINAPI revcMeesage(LPVOID param)
{SOCKET client = (SOCKET)param;char buff[0x100]{ 0 };while (recv(client, buff, 0x100, 0)>0){printf("%s\n",buff);}return 0;
}int main()
{//1.初始化网络环境WSADATA data{ 0 };WSAStartup(MAKEWORD(2, 2), &data);//2.创建SOCKETSOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//3绑定端口号IP地址sockaddr_in serverAddr{ 0 };serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(8888);inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);int result = connect(client, (SOCKADDR*)&serverAddr, sizeof(serverAddr));if (result != 0){printf("连接服务器失败!\n");}HANDLE hthread=CreateThread(NULL, NULL, revcMeesage, (LPVOID)client, NULL, NULL);char buff[0x100]{0};while (scanf_s("%s", buff,0x100) && strcmp(buff,"exit")){send(client,buff,strlen(buff)+1,0);}closesocket(client);CloseHandle(hthread);return 0;
}
相关文章:
网络编程(一)网络编程入门
本节课学习TCP客户端和服务器端编程架构,其分为分为C/S(客户端/服务器模式)和B/S(浏览器/服务器架构模式)两种模式。接下来我们分别了解这两种模式 C/S模式 C/S模式:服务器首先先启动,并根据客…...
华为IP(6)
VLAN聚合 VLAN聚合产生的技术背景 在一般是三层交换机中,通常采用一个VLAN接口的方式实现广播域之间的互通,这在某些情况下导致了IP地址的浪费 因为一个VLAN对应的子网中,子网号、子网广播地址、子网网关地址不能用作VLAN内的主机IP地址&a…...
初探机器学习与深度学习
本文以水果摊销量预测为例,揭示机器学习通过数据训练模型的核心逻辑,对比传统编程规则驱动模式。解析分类(疾病诊断)与回归(房价预测)两大任务的技术本质,类比前端开发中的类型定义与图表拟合。…...
3. 仓颉 CEF 库封装
文章目录 1. capi 使用说明2. Cangjie CEF2. 1实现目标 3. 实现示例 1. capi 使用说明 根据上一节 https://blog.csdn.net/qq_51355375/article/details/147880718?spm1011.2415.3001.5331 所述, cefcapi 是libcef 共享库导出一个 C API, 而以源代码形式分发的 li…...
Linux-TCP套接字编程简易实践:实现EchoServer与远程命令执行及自定义协议(反)序列化
一.TCP Socket常用API 1.1socket() NAMEsocket - create an endpoint for communicationSYNOPSIS#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol); socket()打开一个网络通讯端口,如果…...
缓存(3):本地缓存作用 及 数据一致性 实现策略
概述 CAP 什么是CAP CAP理论,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。 三者关系如…...
【leetcode】《BFS扫荡术:如何用广度优搜索征服岛屿问题》
前言 🌟🌟本期讲解关于力扣的几篇题解的详细介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废话不…...
vue中理解MVVM
理解 在 Vue 中,MVVM(Model-View-ViewModel) 是其核心设计思想之一,它帮助实现了数据驱动的视图更新和良好的代码结构分离。我们来具体解析 Vue 是如何实现 MVVM 模式的。 🌐 MVVM 是什么? 角色含义Vue…...
[工具]B站缓存工具箱 (By 郭逍遥)
📌 项目简介 B站缓存工具箱是一个多功能的B站缓存工具,包含视频下载、缓存重载、文件合并及系统设置四大核心功能。基于yutto开发,采用图形化界面操作,极大简化B站资源获取与管理流程。 工具可以直接将原本缓存的视频读取&#…...
Docker Compose 完全指南:从入门到生产实践
Docker Compose 完全指南:从入门到生产实践 1. Docker Compose 简介与核心价值 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件来配置应用的服务,只需简单命令就能创建和启动所有服务。 核心优势:…...
《Redis应用实例》学习笔记,第二章:缓存二进制数据
前言 最近在学习《Redis应用实例》,这本书并没有讲任何底层,而是聚焦实战用法,梳理了 32 种 Redis 的常见用法。我的笔记在 Github 上,用 Jupyter 记录,会有更好的阅读体验,作者的源码在这里:h…...
ARM GIC(七)亲和路由:GICD_IROUTER寄存器具体如何与MPIDR配合使用?
ARM GIC(一) GIC V3架构基础学习笔记 完善亲和路由章节。 一、MPIDR MPIDR(Multiprocessor Affinity Register)寄存器在ARM架构中用于标识处理器的亲和性信息,这对于中断处理非常重要,特别是在多处理器系…...
stm32之SPI
目录 1.SPI通信协议1.1 简介1.2 硬件电路1.3 移位示意图1.4 SPI时序基本单元1.5 SPI时序 2.W25Q642.1 简介2.2 硬件电路2.3 框图2.3.1 结构介绍2.3.2 混淆 2.4 Flash操作注意事项2.4.1 写操作2.4.2 读取操作 2.5 芯片手册补充2.5.1 状态寄存器2.5.2 指令集 3.软件操作W25Q644.S…...
数据库事务以及JDBC实现事务
一、数据库事务 数据库事务(Database Transaction)是数据库管理系统中的一个核心概念,它代表一组操作的集合,这些操作要么全部执行成功,要么全部不执行,即操作数据的最小执行单元,保证数据库的…...
C语言_函数调用栈的汇编分析
在 C 语言的底层实现中,函数调用栈是程序运行时内存管理的核心机制。它不仅负责函数间的控制转移,还管理局部变量、参数传递和返回值。本文将结合 C 语言代码和 x86-64 汇编指令,深入解析函数调用栈的工作原理。 一、函数调用栈的基本概念 …...
单片机调用printf概率性跑飞解决方法
最近移植软件到不同平台的单片机上时,遇到了软件概率性跑飞的问题,分析后原因均指向和printf相关的库函数(包括sprintf, vsnsprinft),在任务里调用这些函数就有概率在ucos切换任务时跑飞(中断)。…...
无人机空中物流优化:用 Python 打造高效配送模型
友友们好! 我是Echo_Wish,我的的新专栏《Python进阶》以及《Python!实战!》正式启动啦!这是专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会…...
【RP2350】香瓜树莓派RP2350之低功耗
本文最后修改时间:2025年05月10日 01:57 一、本节简介 本节以树莓派pico2开发板为例,举例如何写一个低功耗驱动。 二、实验平台 1、硬件平台 1)树莓派pico2开发板 ①树莓派pico2开发板(作为仿真器) ②micro usb数…...
招行数字金融挑战赛数据赛道赛题一
赛题描述:根据提供的用户行为数据,选手需要分析用户行为特征与广告内容的匹配关系,准确预测用户对测试集广告的点击情况,通过AUC计算得分。 得分0.6120,排名60。 尝试了很多模型都没有能够提升效果,好奇大…...
仿真生成激光干涉包裹相位数据-用于深度学习训练!
该MATLAB/Octave代码实现了论文[1]中提出的相位提取算法,用于从灰度条纹图案中提取包裹相位图(相位值在-π到+π之间)。代码首先生成模拟的条纹图案,包含背景光、调制光和相位分布,并加入高斯噪声。随后,通过N步相移算法估计背景光和调制光,并计算包裹相位。结果显示包括…...
命令行解释器中shell、bash和zsh的区别
命令行解释器(Command Line Interpreter)是一个程序,它的主要作用是接收用户输入的命令,并执行相应的操作。它充当了用户与操作系统内核之间的桥梁。 一、什么是 Shell? Shell 是一个通用术语,指的是 命令…...
SQL 数据库监控:SQL语句监控工具与实践案例
SQL 数据库监控:SQL语句监控工具与实践案例 SQL语句监控的主要方法 SQL监控主要通过以下几种方式实现: 数据库内置监控功能:大多数数据库系统提供内置的SQL监控工具数据库性能视图/系统表:通过查询特定的系统视图获取SQL执行信…...
招行数字金融挑战赛数据分析赛带赛题二
赛题描述:根据提供的脱敏资讯新闻数据,选手需要对提供的训练集进行特征工程,构建资讯分类模型,对与测试集进行准确的新闻分类。 最终得分:0.8120。十二点关榜没看到排名,估算100? 训练集很小&am…...
llama.cpp初识
Llama.cpp:赋能本地大语言模型推理的核心引擎及其应用场景 引言:Llama.cpp 是什么? 大型语言模型 (LLM) 的兴起正在深刻改变人机交互和信息处理的方式。然而,这些强大的模型通常需要巨大的计算资源,使得它们在云端之…...
【EBNF】EBNF:扩展巴克斯-诺尔范式文件格式与实用写法详解
EBNF:扩展巴克斯-诺尔范式文件格式与实用写法详解 一、什么是 EBNF? Extended Backus-Naur Form (EBNF)是一种形式化的语法,用于指定编程语言或其他形式化语言的结构。它是Backus-Naur形式(BNF)的扩展,最初…...
Go语言运算符详解
文章目录 1. 算术运算符2. 关系运算符3. 逻辑运算符4. 位运算符5. 赋值运算符6. 其他运算符运算符优先级注意事项 Go语言提供了与其他语言类似的运算符,包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符等。这些运算符即可满足基本的运算需求。 1. 算…...
MySQL用户管理
目录 一、用户用户信息创建用户删除用户从远端登录修改用户密码 二、数据库的权限给用户授权回收权限 与Linux操作系统类似,MySQL中也有超级用户和普通用户之分。,如果一个用户只需要访问MySQL中的某一个数据库,甚至数据库中的某一个表&#…...
视频编解码学习三之显示器续
一、现在主流的显示器是LCD显示器吗? 是的,现在主流的显示器仍然是 LCD(液晶显示器,Liquid Crystal Display),但它已经细分为多种技术类型,并和其他显示技术(如OLED)形成…...
VSCode1.101.0便携版|中英文|编辑器|安装教程
软件介绍 Visual Studio Code是微软推出的一个强大的代码编辑器,功能强大,操作简单便捷,还有着良好的用户界面,设计得很人性化,旨在为所有开发者提供一款专注于代码本身的免费的编辑器。 软件安装 1、 下载安装包…...
Scala 中累加器的创建与使用格式详解
1. 内置累加器的创建与使用格式 1.1 创建内置累加器 // 通过 SparkContext 创建 val acc sc.longAccumulator("累加器名称") // Long 类型(默认初始值 0) val accDouble sc.doubleAccumulator("累加器名称") // Double 类型&a…...
【DNDC模型】双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的应用
由于全球变暖、大气中温室气体浓度逐年增加等问题的出现,“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会议上讲到,要把“双碳”纳入经济社会发展和生态文明建设整体布局。同时,提到要把减污降碳协同增效作为促…...
深入剖析缓存与数据库一致性:Java技术视角下的解决方案与实践
一、缓存与数据库一致性问题根源 读写分离的架构矛盾 缓存作为数据库的“副本”,天然存在数据同步延迟。 高频读写场景下,缓存与数据库的更新顺序、失败重试等操作易引发不一致。 经典问题场景 场景1:先更新数据库,再删除缓存。…...
Anaconda环境中conda与pip命令的区别
文章目录 conda与pip的基本区别在Anaconda环境中的实际差异安装包环境管理依赖解决示例最佳实践建议 常见问题解答 conda与pip的基本区别 包来源与生态系统 conda:从Anaconda默认仓库或conda-forge等渠道获取包 不仅管理Python包,还能管理非Python依赖&…...
使用FastAPI和React以及MongoDB构建全栈Web应用05 FastAPI快速入门
一、FastAPI概述 1.1 什么是FastAPI FastAPI is a modern, high-performance Python web framework designed for building APIs. It’s rapidly gaining popularity due to its ease of use, speed, and powerful features. Built on top of Starlette, FastAPI leverages a…...
每日c/c++题 备战蓝桥杯(P1002 [NOIP 2002 普及组] 过河卒)
洛谷P1002 [NOIP 2002 普及组] 过河卒 题解 题目描述 过河卒是一道经典的动态规划题目。题目大意是:一个卒子从棋盘左上角(0,0)出发,要走到右下角(n,m),棋盘上有一个马在(x,y)位置,卒子不能经过马所在位置及其周围8个位置。求卒…...
kubectl系列(十二):查询pod的resource 配置
在 Kubernetes 中,可以通过 kubectl 命令快速查询 Pod 的资源请求(requests)和限制(limits)配置。以下是多种方法实现这一目标: 1. 查看 Pod 的资源请求和限制(基础版) 使用 kubec…...
前端面试2
1. 面试准备 1. 建立自己的知识体系 思维导图ProcessOn框架Vue elementUI自查 https://zh.javascript.info/ 借鉴 https://juejin.cn/post/6844904103504527374http://conardli.top/blog/article/https://github.com/mqyqingfeng/Bloghttp://47.98.159.95/my_blog/#html 2.技能…...
使用 Java 反射动态加载和操作类
Java 的反射机制(Reflection)是 Java 语言的一大特色,它允许程序在运行时检查、加载和操作类、方法、字段等元信息。通过 java.lang.Class 和 java.lang.reflect 包,开发者可以动态加载类、创建实例、调用方法,甚至在运行时构造新类。反射是 Java 灵活性的核心,广泛应用于…...
基于Dockers的Bitwarden的私有本地部署
基于Dockers的Bitwarden的私有本地部署 文章目录 基于Dockers的Bitwarden的私有本地部署 本文首发地址 https://h89.cn/archives/355.html bitwarden 默认连接的是国外服务器 https://bitwarden.com/ ,连接不是很稳定,也没有安全感,所以我选择…...
spark-Schema 定义字段强类型和弱类型
在数据处理和存储中,Schema(模式)定义了数据的结构和字段属性,其中字段的强类型和弱类型是重要的概念,直接影响数据的验证、存储和处理方式。以下是详细解释: 1. 强类型(Strongly Typed&#x…...
【第35节 数据库设计】
本章目录: 一、节概述二、知识详解1. 数据库设计的基本步骤2. 用户需求分析3. 概念结构设计(E-R建模)4. 逻辑结构设计5. 物理结构设计6. 数据库实施7. 数据库运行维护8. 商业智能(BI)与数据仓库数据仓库的特点: 9. OLT…...
C++基本知识 —— 缺省参数·函数重载·引用
C基本知识 —— 缺省参数函数重载引用 1. 缺省参数2. 函数重载3. 引用3.1 引用的基础知识3.2 引用的作用3.3 const 引用3.4 指针与引用的关系 1. 缺省参数 什么是缺省参数?缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数的时候,如…...
大数据基础——Ubuntu 安装
文章目录 Ubuntu 安装一、配置电脑二、安装系统 Ubuntu 安装 一、配置电脑 1、进入VMware 2、选择配置类型 3、选择硬件兼容性版本 4、当前虚拟机的操作系统 选择“稍后安装操作系统”(修改) 5、选择虚拟机将来需要安装的系统 选中“Linux”和选择…...
英伟达微调qwen2.5-32B模型,开源推理模型:OpenCodeReasoning-Nemotron-32B
一、模型概述 OpenCodeReasoning-Nemotron-32B 是一个大型语言模型,基于 Qwen2.5-32B-Instruct 开发,专为代码生成推理任务进行了后续训练,支持 32,768 个标记的上下文长度,适用于商业和非商业用途。 二、性能表现 在 LiveCode…...
苍穹外卖-创建阿里云oss工具包
添加配置信息: sky:alioss:endpoint: ***access-key-id: ***access-key-secret: ***bucket-name: *** 把配置的内容转换成对象: Component ConfigurationProperties(prefix "sky.alioss") Data public class AliOssProperties {private St…...
代码随想录训练营第二十一天 |589.N叉数的前序遍历 590.N叉树的后序遍历
589.N叉数的前序遍历: 状态:已做出 思路: N叉树的前序遍历和二叉树很像,我这里使用栈来实现。首先把根结点入栈,然后删除栈顶节点后把栈顶节点的所有子树都插入到栈,这里需要注意的是插入的方式是从最后一…...
鸿蒙跨平台开发教程之Uniapp布局基础
前两天的文章内容对uniapp开发鸿蒙应用做了一些详细的介绍,包括配置开发环境和项目结构目录解读,今天我们正式开始写代码。 入门新的开发语言往往从Hello World开始,Uniapp的初始化项目中已经写好了一个简单的demo,这里就不再赘述…...
面试中常问的设计模式及其简洁定义
🎯 一、面试中常问的设计模式及其简洁定义 模式名常被问到解释(简洁)单例模式✅ 高频保证一个类只有一个实例,并提供全局访问点。工厂模式✅ 高频创建对象的接口由子类决定,屏蔽了对象创建逻辑。抽象工厂模式✅提供多…...
关于 js:6. 网络与加密模块
一、AJAX AJAX(Asynchronous JavaScript And XML) 异步 JavaScript 与 XML(现在多为 JSON) 它允许网页在不重新加载整个页面的情况下,从服务器请求数据并更新页面内容。 主要用途: 提交表单时无需刷新页…...
量化交易系统开发经验分享--回测框架调研
一、前言 这段时间在集中做一个量化交易系统的开发任务,目前系统的MVP已经完成开发,后续会整理一些经验与成果和大家交流。刚好有一个前期做策略回测这块的调研,下面把调研的成果做一个整理总结先给大家分享一下,请批评指正。 在介…...