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

【Linux网络与网络编程】04.TCP Socket编程

一、TCP Socket编程接口

// 创建套接字
int socket(int domain, int type, int protocol);
// 参数:
//		domain:域(协议家族),这里使用 AF_INET 表示进行网络编程
//		type:网络通信传输的类型,这里选择 SOCK_STREAM表示是使用TCP协议的面向数据报传递信息
//		protocol:这个参数目前置0即可
// 返回值:成功则返回一个文件描述符(所以创建套接字的本质就是创建了一个文件);失败则返回-1,并设置对应的错误码// 填充网络信息并绑定
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 参数:
//		sockfd:套接字文件描述符
//		addr:这是为了统一socket接口而定义的数据结构,其中的 sockaddr_in 是我们今天网络通信所要用到的,我们需要在绑定之前设置好它的协议家族,端口号和ip地址
//		addrlen:这是将addr的大小传递给内核,方便判断是哪种addr
// 返回值:成功返回0;失败则返回-1,并设置对应的错误码// TCP是面向连接的,连接成功后才能进行通信,因此要求TCP要随时随地等待被连接
// 监听
int listen(int sockfd, int backlog);
// 参数:
//		sockfd:被设置为监听状态的sockfd
//		backlog:最大连接个数
// 返回值:成功返回0;失败则返回-1,并设置对应的错误码// 获取新连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// 参数:
//		sockfd:监听的sockfd
//		addr:请求连接的addr结构
//		addrlen:请求连接的addr结构的大小
// 返回值:成功返回一个用于服务的sockfd;失败则返回-1,并设置对应的错误码// 客户端不需要bind,首次connect是被自动绑定
// 连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 参数:
//		sockfd:客户端想要去连接的sockfd
//		addr和addrlen:目标主机的addr结构
// 返回值:成功返回0;失败则返回-1,并设置对应的错误码

二、TCP Socket编程

2.1 EchoSever

这里我们来仿照UDP的Echo写一个EchoSever来快速熟悉接口。

//TCPSever.hpp
#pragma once
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "InetAddr.hpp"
#include "Log.hpp"using namespace LogMudule;const static uint16_t defaultport = 8888;class TCPSever
{
public:TCPSever(uint16_t port = defaultport) : _addr(port){// 创建套接字int n = _listensockfd = ::socket(AF_INET, SOCK_STREAM, 0);if (n < 0){LOG(LogLevel::FATAL) << "socket failed";exit(1);}LOG(LogLevel::INFO) << "socket succeed";// 绑定n = ::bind(_listensockfd, _addr.NetAddr(), _addr.Len());if (n < 0){LOG(LogLevel::FATAL) << "bind failed";exit(1);}LOG(LogLevel::INFO) << "bind succeed";// 开始监听n = ::listen(_listensockfd, 5);if (n < 0){LOG(LogLevel::FATAL) << "listen failed";exit(1);}LOG(LogLevel::INFO) << "listen succeed";}void Run(){while(true){//获取连接struct sockaddr_in connected_addr;socklen_t len=sizeof(connected_addr);int sockfd=::accept(_listensockfd,(struct sockaddr*)&connected_addr,&len);if(sockfd<0){LOG(LogLevel::ERROR)<<"accept failed";continue;}InetAddr peer(connected_addr);LOG(LogLevel::INFO)<<"accept succeed connected is "<<peer.Addr() <<" sockfd is "<<sockfd;//既然可以获取到信息了,那么下一步就是提供服务了Service(sockfd);//完成之后就要关闭sockfd::close(sockfd);}}~TCPSever() {::close(_listensockfd);}
private:void Service(int sockfd){char buff[1024];while(true){//TCP是面向字节流的,故而可以采用文件的接口进行读取和写入int n=::read(sockfd,buff,sizeof(buff)-1);if(n>0){buff[n]=0;std::string message="Client Say@";message+=buff;int m=::write(sockfd,message.c_str(),message.size());if(m<0) {LOG(LogLevel::ERROR)<<"write failed";}}else if(n==0){//表示读到了文件末尾LOG(LogLevel::INFO)<<"Client Quit……";break;}else{LOG(LogLevel::ERROR)<<"read error";break;}}}private:int _listensockfd;InetAddr _addr;
};
//TCPSever.cc
#include "TCPSever.hpp"
int main()
{std::unique_ptr<TCPSever> ts_ptr=std::make_unique<TCPSever>();ts_ptr->Run();return 0;
}

再来完成我们的客户端代码:

// TCPClient.hpp
#pragma once
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include "Log.hpp"
#include "InetAddr.hpp"using namespace LogMudule;
const static std::string defaultip="127.0.0.1";
const static int defaultport=8888;class TCPClient
{
public:TCPClient(std::string ip,uint16_t port):_dst_addr({ip,port}){//创建套接字_sockfd=::socket(AF_INET,SOCK_STREAM,0);if(_sockfd<0){LOG(LogLevel::FATAL)<<"socket failed";exit(1);}LOG(LogLevel::INFO)<<"socket succeed";//不需要绑定}void Run(){cout<<_sockfd<<endl;int n=::connect(_sockfd,_dst_addr.NetAddr(),_dst_addr.Len());if(n<0){LOG(LogLevel::ERROR)<<"connect failed";exit(3);}LOG(LogLevel::INFO)<<"connect succeed";while(true){std::string message;std::getline(std::cin,message);cout<<"message is:"<<message<<endl;::write(_sockfd,message.c_str(),message.size());char buff[1024];n=::read(_sockfd,buff,sizeof(buff)-1);if(n>0){buff[n]=0;std::cout<<buff<<std::endl;}}}~TCPClient(){::close(_sockfd);}private:int _sockfd;InetAddr _dst_addr;
};
//TCOClient.cc
#include <memory>
#include "TCPClient.hpp"int main(int argc,char* argv[])
{if(argc!=3){std::cout<<"Usgae Error"<<std::endl;exit(-1);}std::string ip=argv[1];uint16_t port=std::stoi(argv[2]);std::unique_ptr<TCPClient> c_ptr=std::make_unique<TCPClient>(ip,port);c_ptr->Run();return 0;
}

这段客户端的代码我们就写好了,简单的测试过后可以发现是可以的。本篇博客采用telnet来充当客户端进行测试:
在这里插入图片描述
可以见得我们的服务端的代码逻辑也是正确的,接下来我们要实现多线程和多进程的EchoSever

进程分离管理:

//……
void Run()
{while (true){// 2. 进程分离版本,子进程执行任务,父进程来进行监听// 获取连接struct sockaddr_in connected_addr;socklen_t len = sizeof(connected_addr);int sockfd = ::accept(_listensockfd, (struct sockaddr *)&connected_addr, &len);if (sockfd < 0){LOG(LogLevel::ERROR) << "accept failed";continue;}InetAddr peer(connected_addr);LOG(LogLevel::INFO) << "accept succeed connected is " << peer.Addr() << " sockfd is " << sockfd;int id = fork();if (id == 0){// 子进程::close(_listensockfd);// 子进程再次创建子进程,子进程返回,避免父进程阻塞,孙子进程为孤儿进程,被OS领养if(fork()>0)    exit(0);Service(sockfd);exit(0);}else{// 父进程::close(sockfd);int rid=::waitpid(id,nullptr,0);if(rid<0){LOG(LogLevel::ERROR) << "waitpid failed";}}}
}
//……

线程分离管理:

//……
// 3. 线程分离管理
struct ThreadData
{int _sockfd;TCPSever *_self;
};
static void *Handler(void *args)
{pthread_detach(pthread_self());ThreadData* data=(ThreadData*)args;data->_self->Service(data->_sockfd);return nullptr;
}
//……
void Run()
{while (true){// 3.线程管理版本的// 获取连接struct sockaddr_in connected_addr;socklen_t len = sizeof(connected_addr);int sockfd = ::accept(_listensockfd, (struct sockaddr *)&connected_addr, &len);if (sockfd < 0){LOG(LogLevel::ERROR) << "accept failed";continue;}InetAddr peer(connected_addr);LOG(LogLevel::INFO) << "accept succeed connected is " << peer.Addr() << " sockfd is " << sockfd;ThreadData* data=new ThreadData;data->_sockfd=sockfd;data->_self=this;pthread_t tid; pthread_create(&tid, nullptr, Handler, data);}
}

线程池管理:

//……
void Run()
{while (true){// 4.线程池管理版本struct sockaddr_in connected_addr;socklen_t len = sizeof(connected_addr);int sockfd = ::accept(_listensockfd, (struct sockaddr *)&connected_addr, &len);if (sockfd < 0){LOG(LogLevel::ERROR) << "accept failed";continue;}InetAddr peer(connected_addr);LOG(LogLevel::INFO) << "accept succeed connected is " << peer.Addr() << " sockfd is " << sockfd;//绑定生成任务task_t task=std::bind(&TCPSever::Service,this,sockfd);ThreadPool<task_t> ::GetInstance()->Enqueue(task);}
}
//……

2.2 远程命令执行

//command.hpp
#pragma once
#include <string>
#include <cstring>
#include "Log.hpp"using namespace LogMudule;class Command
{
public:std::string Excute(const std::string &command){// 相当于pipe + exclFILE *fp = popen(command.c_str(), "r");if (fp == nullptr)return std::string();char buffer[1024];std::string result;while (fgets(buffer, sizeof(buffer), fp)){result += buffer;}pclose(fp);return result;}
};
//TCPSever.hpp
#pragma once
#include <string>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
#include "InetAddr.hpp"
#include "Log.hpp"
#include "ThreadPool.hpp"using namespace LogMudule;
using namespace ThreadPoolModual;const static uint16_t defaultport = 8888;using task_t = std::function<void()>;
using command_t = std::function<std::string(const std::string)>;class TCPSever
{void Service(int sockfd){char buff[1024];while (true){// TCP是面向字节流的,故而可以采用文件的接口进行读取和写入int n = ::read(sockfd, buff, sizeof(buff) - 1);if (n > 0){//网络传输中以\r\n结尾buff[n-2] = 0;std::string message = _command(buff);int m = ::send(sockfd, message.c_str(), message.size(),0);if (m < 0){LOG(LogLevel::ERROR) << "write failed";}}else if (n == 0){// 表示读到了文件末尾LOG(LogLevel::INFO) << "Client Quit……";break;}else{LOG(LogLevel::ERROR) << "read error";break;}}}public:TCPSever(command_t command, uint16_t port = defaultport) : _command(command), _addr(port){// 创建套接字int n = _listensockfd = ::socket(AF_INET, SOCK_STREAM, 0);if (n < 0){LOG(LogLevel::FATAL) << "socket failed";exit(1);}LOG(LogLevel::INFO) << "socket succeed";// 绑定n = ::bind(_listensockfd, _addr.NetAddr(), _addr.Len());if (n < 0){LOG(LogLevel::FATAL) << "bind failed";exit(1);}LOG(LogLevel::INFO) << "bind succeed";// 开始监听n = ::listen(_listensockfd, 5);if (n < 0){LOG(LogLevel::FATAL) << "listen failed";exit(1);}LOG(LogLevel::INFO) << "listen succeed";}void Run(){while (true){// 4.远程执行任务struct sockaddr_in connected_addr;socklen_t len = sizeof(connected_addr);int sockfd = ::accept(_listensockfd, (struct sockaddr *)&connected_addr, &len);if (sockfd < 0){LOG(LogLevel::ERROR) << "accept failed";continue;}InetAddr peer(connected_addr);LOG(LogLevel::INFO) << "accept succeed connected is " << peer.Addr() << " sockfd is " << sockfd;// 绑定生成任务task_t task = std::bind(&TCPSever::Service, this, sockfd);ThreadPool<task_t>::GetInstance()->Enqueue(task);}}~TCPSever(){::close(_listensockfd);}private:int _listensockfd;InetAddr _addr;command_t _command;
};

三、Windows下的TCP Socket

#include <winsock2.h>
#include <iostream>
#include <string>
#pragma warning(disable : 4996)
#pragma comment(lib, "ws2_32.lib")
std::string serverip = "62.234.18.77"; // 填写你的云服务器 ip
uint16_t serverport = 8888; // 填写你的云服务开放的端口号
int main()
{WSADATA wsaData;int result = WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0){std::cerr << "WSAStartup failed: " << result << std::endl;return 1;}SOCKET clientSocket = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);if (clientSocket == INVALID_SOCKET){std::cerr << "socket failed" << std::endl;WSACleanup();return 1; }sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(serverport);serverAddr.sin_addr.s_addr = inet_addr(serverip.c_str());result = connect(clientSocket, (SOCKADDR*)&serverAddr,sizeof(serverAddr));if (result == SOCKET_ERROR){std::cerr << "connect failed" << std::endl;closesocket(clientSocket);WSACleanup();return 1;}while (true){std::string message;std::cout << "Please Enter@ ";std::getline(std::cin, message);if (message.empty()) continue;send(clientSocket, message.c_str(), message.size(), 0);char buffer[1024] = { 0 };int bytesReceived = recv(clientSocket, buffer,sizeof(buffer) - 1, 0);if (bytesReceived > 0){buffer[bytesReceived] = '\0'; // 确保字符串以 null 结尾std::cout << "Received from server: " << buffer <<std::endl;}else{std::cerr << "recv failed" << std::endl;}}closesocket(clientSocket);WSACleanup();return 0;
}

最后附上跨平台测试截图:
在这里插入图片描述

相关文章:

【Linux网络与网络编程】04.TCP Socket编程

一、TCP Socket编程接口 // 创建套接字 int socket(int domain, int type, int protocol); // 参数&#xff1a; // domain&#xff1a;域&#xff08;协议家族&#xff09;&#xff0c;这里使用 AF_INET 表示进行网络编程 // type&#xff1a;网络通信传输的类型&#xff0…...

初识数据结构——算法效率的“两面性”:时间与空间复杂度全解析

&#x1f4ca; 算法效率的“两面性”&#xff1a;时间与空间复杂度全解析 1️⃣ 如何衡量算法好坏&#xff1f; 举个栗子&#x1f330;&#xff1a;斐波那契数列的递归实现 public static long Fib(int N) {if(N < 3) return 1;return Fib(N-1) Fib(N-2); }问题&#xf…...

CCF GESP C++编程 八级认证真题 2025年3月

C 八级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 答案 B C B A D D D 一、单选题 第 1 题 国家“以旧换新”政策仍在继续&#xff0c;小杨家决定在家里旧的冰箱、电视、洗衣机、微波炉中选两种换新。其中&#xff0c;冰箱有4种型号可选&#xff0c;电视有6种型号可选&#xff0c…...

React: hook相当于函数吗?

一、Hook 是一个函数&#xff0c;但不仅仅是函数 函数的本质 Hook 确实是一个 JavaScript 函数&#xff0c;例如 useState、useEffect 或自定义 Hook 都是函数。它们可以接受参数&#xff08;如初始状态值或依赖项数组&#xff09;&#xff0c;并返回结果&#xff08;如状态值和…...

Git 从入门到精通(开源协作特别版)

&#x1f9e0; Git 从入门到精通&#xff08;开源协作特别版&#xff09; ✅ 基础命令 &#x1f9f0; 高级用法 &#x1f6e0;️ 开源实战技巧 &#x1f30d; GitHub 社区协作 适合&#xff1a;从0开始 → 熟练开发者 → 参与/维护开源项目 &#x1f530; 第1章&#xff1a;…...

《探索边缘计算:重塑未来智能物联网的关键技术》

最近研学过程中发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...

什么是缓存穿透、缓存雪崩、缓存击穿?

什么是缓存&#xff1f; 缓存就是数据交换的缓冲区&#xff0c;是存贮数据的临时地方&#xff0c;一般读写性能较高。 怎么防止缓存穿透&#xff1f; 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到…...

洛谷题单3-P4956 [COCI 2017 2018 #6] Davor-python-流程图重构

题目描述 在征服南极之后&#xff0c;Davor 开始了一项新的挑战。下一步是在西伯利亚、格林兰、挪威的北极圈远征。 他将在 2018 年 12 月 31 日开始出发&#xff0c;在这之前需要一共筹集 n 元钱。 他打算在每个星期一筹集 x 元&#xff0c;星期二筹集 xk 元&#xff0c;……...

解决浏览器报错Mixed Content

前端代码写死了访问后端的请求为&#xff1a;http://service.xxx.com:8080/api/&#xff0c;前端代码中混合内容&#xff08;Mixed Content&#xff09; 导致的。浏览器使用https访问站点时&#xff0c;这个请求会被拦截&#xff0c;并且浏览器打印 login.vue:151 Mixed Conten…...

HCIP【BGP协议(详解)】

目录 1 BGP协议产生背景 2 BGP协议特性 2.1 自治系统间路由传播 2.2 路由矢量协议 2.3 防环机制 2.4 基于TCP传输 2.5 路由更新机制 2.6 丰富的路由属性 2.7 支持CIDR和路由聚合 2.8 路由过滤和策略控制 2.9 动态对等体功能 3 BGP基本术语 4 BGP规划问题 4.1 路…...

集合与容器:List、HashMap(II)

一、ArrayList 是集合框架中最核心的动态数组实现&#xff0c;高频使用的容器之一。 1. 核心数据结构 基于数组实现&#xff0c;维护elementData数组存储元素&#xff1a; transient修饰的elementData不会被默认序列化&#xff08;通过自定义序列化逻辑优化存储&#xff09;…...

mac 安装MySQL

1、打开官网&#xff0c;点击Downloads 2、在downloads页面选择MySQL Community Server 3、选择对应的设备和版本&#xff0c;点击下载 4、下载选择 5、下载完成后&#xff0c;点击安装 6、next 到Configguration 时要输入密码&#xff08;千万别忘记&#xff09; 7.最后输…...

Pascal语言的软件开发工具

使用Pascal语言的软件开发工具 引言 随着计算机科学的发展&#xff0c;编程语言层出不穷&#xff0c;程序员们在开发时可以选择多种多样的工具。而Pascal语言作为一种历史悠久的程序设计语言&#xff0c;尽管在当今编程语言的生态中已不再是主流&#xff0c;但其优雅的语法和…...

vue组件开发:什么是VUE组件?

什么是VUE组件 在我们实际开发过程中你也许会发现有很多代码是重复的&#xff0c;它们可能是一个按钮、一个表单、一个列表等等&#xff0c;其中最为显著的应该是列表。 以CSDN的首页为例&#xff1a; 上述截图中的文章列表可能会在多处出现&#xff0c;比如此截图是精选博客…...

如何在Springboot的Mapper中轻松添加新的SQL语句呀?

在如今的软件开发界&#xff0c;Spring Boot可是非常受欢迎的框架哦&#xff0c;尤其是在微服务和RESTful API的构建上&#xff0c;真的是让人爱不释手&#xff01;今天&#xff0c;我们就来聊聊如何为Spring Boot项目中的Mapper添加新的SQL语句吧&#xff01;说起来&#xff0…...

微服务架构: SpringCloud服务注册与发现详解

# 微服务架构: SpringCloud服务注册与发现详解 一、什么是微服务架构 微服务架构简介 微服务架构&#xff08;Microservices Architecture&#xff09;是一种以一组小型服务应用程序构建系统的软件架构风格。每个服务运行在自己的进程中&#xff0c;通过精简的HTTP API进行通信…...

现代简约杂志海报包装网页设计无衬线英文字体安装包 Seriusans – Condensed Sans Display Font

Seriusans 是一种 Condensed Sans Display 字体&#xff0c;将现代简约与大胆融为一体。其狭窄而醒目的字体营造出强大的存在感&#xff0c;使其成为有影响力设计的绝佳选择&#xff0c;例如海报、杂志标题、品牌、包装、网页设计、运动图形、社论布局、广告活动、企业演示&…...

C/C++的条件编译

一、什么是条件编译&#xff1f; 条件编译是指在编译阶段根据某些条件来决定是否编译某段代码。这通常通过预处理指令来实现&#xff0c;比如 #if、#ifdef、#ifndef、#else、#elif 和 #endif。 二、为什么使用条件编译&#xff1f; ​​跨平台开发​​&#xff1a;不同的操作…...

视野,,地面覆盖,重叠需求,FPS,飞行速度等的计算公式

一、计算相机视野与重叠需求 1. 相机参数 IDS UI-5280CP&#xff1a; 分辨率&#xff1a;2456x2054 像素。传感器&#xff1a;假设为 1/1.8" CMOS&#xff08;常见型号&#xff09;&#xff0c;尺寸约 6.78 mm&#xff08;宽&#xff09; 5.67 mm&#xff08;高&#xf…...

ARXML文件解析-1

目录 1 摘要2 ARXML文件2.1 作用及典型应用场景2.2 **ARXML文件的结构树**2.3 TAG&#xff08;XML元素&#xff09;2.4 ARXML文件关键元素解析2.4.1 XML声明与处理指令2.4.2 XML注释2.4.3 ADMIN-DATA元素2.4.3 语言相关元素2.4.5 AR-PACKAGE体系结构2.4.6. 数据转换框架2.4.7 S…...

传统开发者视角:智能合约与区块链数据库探秘

前言 在上一篇文章:探秘区块链开发:智能合约在 DApp 中的地位及与传统开发差异中我为大家从传统开发者的角度讲解了一下什么是智能合约。 简单的来说智能合约对于传统前端开发者可以说是API接口,而后端开发者则可以说是负责接口逻辑的程序。 然而从传统的开发意识跳跃到D…...

游戏引擎学习第204天

回顾并为今天的内容做铺垫 好&#xff0c;现在开始这一集。今天我们将进行一些用户界面编程&#xff0c;觉得这是一个展示如何编写这类代码的好时机。很多人对如何做用户界面代码都很好奇&#xff0c;所以展示一下如何编写是非常有意义的。 我之所以在现在的这个地方做这些工…...

蓝桥杯2024年第十五届省赛真题-R 格式

题目链接&#xff1a; 思路&#xff1a; 通过数组模拟d的每一位&#xff0c;逐位进行计算&#xff0c;从而实现对d的精确处理。 代码&#xff1a; #include<bits/stdc.h> #define int long long using namespace std; const int N 2020;int n; string s; vector<i…...

Haskell语言的区块链安全

Haskell语言在区块链安全中的应用 引言 随着区块链技术的发展&#xff0c;它已经成为金融、供应链管理、身份认证等多个领域的重要基础设施。然而&#xff0c;区块链的安全性问题一直是行业关注的焦点。为了确保区块链的安全性&#xff0c;开发者需要选择合适的编程语言来编写…...

BUUCTF-web刷题篇(11)

20.admin 这道题很可能用admin或者伪造admin进行登录&#xff0c;用admin进行登录&#xff0c;随便填写密码进不去&#xff0c;发现页面有register、login&#xff0c;用admin注册提示已经被注册。 方法一&#xff1a;&#xff08;burp爆破&#xff09; 进入登陆界面&#x…...

TensorFlow

TensorFlow 是一个由 Google 开发并开源的机器学习和深度学习库&#xff0c;被广泛应用于各类机器学习项目。以下为你详细介绍&#xff1a; 概述 TensorFlow 最初是为了满足 Google 内部大规模机器学习需求而研发&#xff0c;后于 2015 年开源。它提供了一个强大且灵活的生态…...

分子生成的深层次层次变分自编码器 - DrugHIVE 测评

一、背景介绍 DrugHIVE 来源于南加州大学定量与计算生物学系的 Remo Rohs 为通讯作者的文章&#xff1a;《Structure-Based Drug Design with a Deep Hierarchical Generative Model》。文章链接&#xff1a;https://pubs.acs.org/doi/10.1021/acs.jcim.4c01193。该文章在 202…...

54.大学生心理健康管理系统(基于springboot项目)

目录 1.系统的受众说明 2.相关技术 2.1 B/S结构 2.2 MySQL数据库 3.系统分析 3.1可行性分析 3.1.1时间可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.1.4 技术可行性 3.1.5 法律可行性 3.2系统流程分析 3.3系统功能需求分析 3.4 系统非功能需求分析 4.系统设计…...

Linux文件特殊权限管理及进程和线程

acl 权限优先级 拥有者 > 特殊指定用户 > 权限多的组 >权限少的组 > 其他 mask阈值 mask是能够赋予指定用户权限的最大阀值 当设定完毕文件的acl列表之后用chmod缩小了文件拥有组的权力 mask会发生变化 恢复&#xff1a; setfacl -m m: 权限 :rwx 文件/…...

Vue2+Vue3 45-90集学习笔记

Vue2Vue3 45-90集学习笔记 小兔鲜首页 页面开发思路&#xff1a; 分析页面&#xff0c;按模块拆分组件&#xff0c;搭架子&#xff08;局部注册或全局注册&#xff09; 局部注册&#xff1a;App.js中 导入&#xff08;import&#xff09;&#xff0c;注册&#xff08;compon…...

【Web 服务器】的工作原理

&#x1f310; Web 服务器的工作原理 Web 服务器的主要作用是 接收客户端请求&#xff08;通常是浏览器发出的 HTTP/HTTPS 请求&#xff09;&#xff0c;处理请求&#xff0c;并返回相应的数据&#xff08;如网页、图片、API 响应等&#xff09;。 &#x1f4cc; 工作流程 1️…...

LeetCode 5 -- 区间DP | 中心拓展算法

题目描述 最长回文子串 数据规模为 5e5&#xff0c;必须 manacher 算法 1. DP 由于 r e v e r s e ( ) reverse() reverse() 的时间复杂度是 O ( N ) O(N) O(N)&#xff0c;因此暴力肯定是不行的。 d p dp dp 的思路&#xff1a;如果 s [ l . . r ] s[l..r] s[l..r] 是一个…...

IntelliJ IDEA中Spring Boot 3.4.x+集成Redis 7.x:最新配置与实战指南

‌前言 Spring Boot 3.4.x作为当前‌最新稳定版本‌&#xff0c;全面支持Java 17与Jakarta EE 10规范。本文以‌Spring Boot 3.4.1‌和‌Redis 7.x‌为例&#xff0c;详解如何在IDEA中快速接入Redis&#xff0c;涵盖‌最新依赖配置‌、‌数据序列化优化‌、‌缓存注解‌及‌高…...

数仓建模中计算累计销量

在数仓建模中计算累计销量&#xff0c;通常需要结合时间维度和业务逻辑设计合理的模型与计算逻辑。以下是分步骤的实现思路和示例&#xff1a; 1. 模型设计 累计销量的计算通常基于星型模型或雪花模型&#xff0c;核心结构包括&#xff1a; 事实表&#xff1a;记录每一笔销售…...

(多看) CExercise_05_1函数_1.2计算base的exponent次幂

题目&#xff1a; 键盘录入两个整数&#xff1a;底(base)和幂指数(exponent)&#xff0c;计算base的exponent次幂&#xff0c;并打印输出对应的结果。&#xff08;注意底和幂指数都可能是负数&#xff09; 提示&#xff1a;求幂运算时&#xff0c;基础的思路就是先无脑把指数转…...

Pollard‘s Rho 算法

Pollard’s Rho 算法&#xff1a;一场数学与计算机科学的巧妙结合 在现代计算机科学中&#xff0c;素数分解、整数因子化问题有着广泛的应用&#xff0c;尤其是在密码学领域。然而&#xff0c;当面对一个大合数时&#xff0c;寻找其因子仍然是一个非常复杂的问题。我们常常依赖…...

8款分形长虹玻璃科幻渐变海报设计JPG背景素材 The Gradient Backgrounds Pack

天空从未如此美好 — 直到有人将日落洒在您的屏幕上。这些渐变是带有心跳的液体颜色&#xff0c;从熔化的金色转变为深紫色&#xff0c;就像地平线一样。 8 个背景中的每一个都以 45003000 像素和 300dpi 的速度脉冲&#xff0c;清晰到足以让您感觉自己可以直接踏入光芒中。但这…...

AIGC9——​AIGC时代的用户体验革命:智能交互与隐私保护的平衡术

引言&#xff1a;当AI成为交互主角 2024年&#xff0c;淘宝AI客服"阿里小蜜"日均处理20亿次咨询&#xff0c;日本虚拟偶像"初音未来"演唱会门票3秒售罄——这些现象标志着AIGC已深度融入人机交互场景。但与此同时&#xff0c;过度个性化的推荐引发"信…...

vm虚拟机虚拟出网卡并ping通外网

在 Linux 和 Windows 系统中&#xff0c;即使不使用网络命名空间&#xff08;namespace&#xff09;&#xff0c;也能实现虚拟网卡上网。以下是不同场景下的实现方法&#xff1a; 一、Linux 系统&#xff08;不使用网络命名空间&#xff09; 1. 直接创建虚拟网卡对&#xff08…...

基于时间卷积网络TCN实现电力负荷多变量时序预测(PyTorch版)

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…...

ESXi8的部署过程

目录 一、系统安装 二、ESXI8的序列号 三、挂载硬盘和新建VMFS数据分区 四、通过数据存储浏览器上传下载文件 五、Windows远程桌面端口隐射 六、导出虚机 一、系统安装 1、使用UtrIOS系统制作ESXI8的启动盘; 2、服务器启动F8按键进入Popup启动选项,选择U盘启动; 3、安…...

IntelliJ IDEA 2020~2024 创建SpringBoot项目编辑报错: 程序包org.springframework.boot不存在

目录 前奏解决结尾 前奏 哈&#xff01;今天在处理我的SpringBoot项目时&#xff0c;突然遇到了一些让人摸不着头脑的错误提示&#xff1a; java: 程序包org.junit不存在 java: 程序包org.junit.runner不存在 java: 程序包org.springframework.boot.test.context不存在 java:…...

Windows 权限配置文件解析与安全分析(GPP,GPO,LSA)

在 Windows 网络环境中&#xff0c;权限配置文件用于管理用户权限、密码策略和访问控制&#xff0c;涵盖组策略首选项&#xff08;GPP&#xff09;、本地安全策略&#xff08;LSA&#xff09;、注册表以及 Active Directory 组策略&#xff08;GPO&#xff09; 等。这些配置文件…...

【微服务】基础概念

1.什么是微服务 微服务其实就是一种架构风格&#xff0c;他提倡我们在开发的时候&#xff0c;一个应用应该是一组小型服务而组成的&#xff0c;每一个服务都运行在自己的进程中&#xff0c;每一个小服务都通过HTTP的方式进行互通。他更加强调服务的彻底拆分。他并不是仅局限于…...

MYOJ_4342:(洛谷P1087)[NOIP 2004 普及组] FBI 树(二叉树实操,递归提高)

题目描述 我们可以把由 “0” 和 “1” 组成的字符串分为三类&#xff1a;全 “0” 串称为 B 串&#xff0c;全 “1” 串称为 I 串&#xff0c;既含 “0” 又含 “1” 的串则称为 F 串。 FBI 树是一种二叉树&#xff0c;它的结点类型也包括 F 结点&#xff0c;B 结点和 I 结点三…...

LLM(13):词编码后的位置

原则上&#xff0c;token 嵌入是大型语言模型&#xff08;LLM&#xff09;的合适输入。然而&#xff0c;LLM 的一个小缺点是它们的自注意力机制无法指导序列中 token 的位置或顺序。在前面介绍的嵌入层的工作方式中&#xff0c;无论 token ID 在输入序列中的位置如何&#xff0…...

MINIQMT学习课程Day4

聚宽的模拟/实盘跟单系统&#xff0c;已经全部介绍完毕&#xff0c;上传完毕了&#xff0c;相信大家已经可以进行聚宽的miniqmt的交易了。如果还有疑问&#xff0c;私信我进行沟通。 现在开始进入新的课题&#xff0c;如何学习python&#xff0c;我不教那些乱七八糟的&#xff…...

AWS云服务:大数据公司实现技术突破与商业价值的核心引擎

在数据驱动决策的时代&#xff0c;大数据公司面临着海量数据存储、实时计算、复杂分析及安全合规等核心挑战。如何高效构建弹性、可扩展且低成本的技术架构&#xff0c;成为企业能否在竞争中胜出的关键。亚马逊云科技&#xff08;AWS&#xff09;作为全球云计算领域的领导者&am…...

Openpyxl使用教程(包含处理大数据量案例)

文章目录 一、简介功能特性应用场景使用优势 二、常用方法1、工作簿wb2、工作表ws 三、案例1、创建新工作簿2、将Excel数据存入list中3、按行读取文件(适合大文件)4、按指定行读取文件(适合大文件) 一、简介 在 Python 数据处理领域&#xff0c;openpyxl 凭借其卓越的功能与易…...

蓝桥杯15届 宝石组合

问题描述 在一个神秘的森林里&#xff0c;住着一个小精灵名叫小蓝。有一天&#xff0c;他偶然发现了一个隐藏在树洞里的宝藏&#xff0c;里面装满了闪烁着美丽光芒的宝石。这些宝石都有着不同的颜色和形状&#xff0c;但最引人注目的是它们各自独特的 “闪亮度” 属性。每颗宝…...