【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)

news2025/4/8 15:11:55

基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3)

项目功能
	基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊
	扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等
功能介绍:
	模拟QQ聊天
	
	客户端:
		登录界面:
			1、登录
			2、注册		//将用户注册账户/密码信息存储在数据里
			3、注销
	
	服务器:
			转发信息:主要实现私聊和群聊的功能,只要通过服务器
					进行数据传输,最好都先用json在客户端打包,然后在服务器中解包
					
			处理信息:将从客户端发来的数据存储到数据库等操作
			
	主界面:
			1、添加好友			//是否需要同意
			2、查看我的好友		//显示好友当前状态,是否在线
			3、与好友私聊		//离线的信息怎么处理
			4、删除好友			//单删
			5、创建群聊
			6、开始群聊			//禁言
			7、拉好友进群		//群主和管理员的权限
			8、踢人				//群主和管理员的权限
			9、查看群中好友		//显示群主和管理员的权限、群员的权限
			10、注销账号
			11、公共朋友圈		//朋友圈//小游戏
						
推荐使用TCP通信来实现,因为TCP只需要将客户端的fd存储在数据库,那么我们就可以随时想要客户端的fd然后给其发送信息。
==========================================================
1、画架构图--->实现什么功能
2、设置结构体
3、设置协议
4、设置函数
===================================================
客户端:
	>显示界面
		printf("1、登录    2、注册   3、退出  4、注销");
		
	单独写函数化界面
	Switch(){
			case 1:
						login
						break
			case 2:
						zhuce
						break
			case 3:
						logout
						break
			case 4:	
						zhuxiao
						break
	}
	//用户名:
	密码:
	...........
	send到服务器中---》数据存入数据库
	==================================================================
	服务器:
			1、并发服务器		考虑使用--->进程?线程?
			2、接受客户端的数据
			3、数据的转发
			
	数据库:
			1>打开数据库
					注册---写入
					登录---读取并匹配
					
			2>可以添加相关功能
					
			3>关闭数据库
			
	参考:
			服务器可以使用多路复用取创建线程,每一个线程都是单独和一个客户端进行通信
			客户端登录完成后,创建线程,专门用来接受服务器发送给客户端的信息
			
			数据库:需要多个table
			
			用户总表:储存注册的用户和密码,登录后将他的fd也放进去,下线后再次登录就更新。
			
			好友表:每当一个用户注册就创建一个好友表,里面储存该用户的好友名
			
			群聊总表:存储所有被创建的群聊名
			
			群聊成员总表:存储群聊里面的成员名
	=====================================================================

1. 系统架构设计

🔹 服务器端

	监听客户端连接
	多线程处理每个客户端
	使用 SQLite3 存储用户/好友/群信息
	解析 JSON 数据包
	转发私聊/群聊消息

🔹 客户端

	建立 TCP 连接
	JSON 格式封装数据
	交互界面(菜单选择私聊/群聊等)
	子线程接收服务器消息

🔹 1.1 架构图

+--------------------+          +------------------+
|      客户端       |    TCP/IP  |      服务器      |
+--------------------+ <------> +------------------+
| 1. 登录/注册      |             | 1. 处理用户请求  |
| 2. 添加好友       |             | 2. 保存数据到DB  |
| 3. 私聊/群聊      |             | 3. 发送/转发消息 |
| 4. 退出/注销      |             | 4. 维护在线状态  |
+--------------------+          +------------------+

聊天室实现流程图:(实现框架)
聊天室实现流程图

实现聊天室的登陆、注册流程图

注册:
注册
登陆:登陆
以上实现的编程思路逻辑为:

注册:
1、服务器要先启动,监听客户端的连接;
2、客户端启动,首先连接服务器,并显示登陆、注册界面;
3、服务器接收到客户端连接后,会创建一个子线程专门用于于客户端的通信;
4、选择注册后,提示输入用户名、密码,封装注册信息到结构体变量msg中,并发送该信令给服务器;
5、服务器接收到客户端注册信息后,进入注册处理流程;
6、注册功能:首先在数据库表中查找该用户名是否存在,如果不存在则使flage值为1,并且在数据库表中将该用户名密码保存到数据库中,并返回注册成功的信令;
否则使flage值为-1,并返回 错误信息;
7、客户端接收到服务器注册处理指令后,会打印提示信息,并显示步骤2的菜单。

登陆:
1、服务器要先启动,监听客户端的连接;
2、客户端启动,首先连接服务器,并显示登陆、注册界面;
3、服务器接收到客户端连接后,会创建一个子线程专门用于于客户端的通信;
4、选择登陆后,提示输入用户名、密码,封装登陆信息到结构体变量msg中,并发送该信令给服务器;
5、服务器接收到客户端注册信息后,进入登陆处理流程;
6、登陆功能:首先查找该用户名、密码是否在数据库表中存在匹配项,找到返回对应的下标,并将于该客户端相连接的套接字保存到对应的条目中,返回登陆成功信息给客户端;如果没有找到,则返回-1,并返回错误信息给客户端;
7、客户端接收到服务器注册处理指令后,会打印提示信息,并设置客户端在线的标记login_f 为1,此时会显示 聊天功能对应的菜单。

客户端与服务端:私聊私聊

私聊流程:
1、客户端从菜单选择私聊功能;
2、输入要聊天的对象和聊天信息;
3、发送聊天信息给服务器;
4、服务器的子线程收到私聊数据之后,进入私聊流程;
5、向指定用户发送该私聊信息;

客户端与服务端:公聊
公聊

公聊流程:
1、客户端从菜单选择公聊功能;
2、输入要聊天信息;
3、回车发送聊天信息;
4、服务器的子线程收到公聊数据之后,进入公聊流程;
5、查找所有在线用户,向所有的在线用户发送该公聊信息;
6、客户端进入聊天后会创建一个子线程,该子线程会循环接收所有服务器发送的数据信息。

🔹 1.2 技术选型

组件 技术方案
通信协议 TCP(稳定可靠)
数据格式 JSON(使用 cJSON 解析)
服务器模型 I/O 多路复用(select 或 epoll)+ 线程池
数据库 SQLite3(轻量级)
加密 密码 SHA-256 哈希存储

2. 数据库设计

🔹 2.1 用户表(users)

字段 类型 说明
id INTEGER PRIMARY KEY 用户 ID
username TEXT UNIQUE 用户名
password TEXT SHA-256 哈希存储
status INTEGER 0=离线, 1=在线
fd INTEGER 记录 socket 连接
CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT UNIQUE NOT NULL,
    password TEXT NOT NULL,
    status INTEGER DEFAULT 0,
    fd INTEGER DEFAULT -1
);

🔹 2.2 好友表(friends)

记录用户之间的好友关系。

字段 类型 说明
user_id INTEGER 用户 ID
friend_id INTEGER 好友 ID
CREATE TABLE friends (
    user_id INTEGER,
    friend_id INTEGER,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (friend_id) REFERENCES users(id)
);

🔹 2.3 群聊表(groups)

记录群聊信息。

字段 类型 说明
group_id INTEGER PRIMARY KEY 群 ID
group_name TEXT UNIQUE 群名称
owner_id INTEGER 群主 ID
CREATE TABLE groups (
    group_id INTEGER PRIMARY KEY AUTOINCREMENT,
    group_name TEXT UNIQUE NOT NULL,
    owner_id INTEGER NOT NULL,
    FOREIGN KEY (owner_id) REFERENCES users(id)
);

🔹 2.4 群成员表(group_members)

记录群聊成员及身份。

字段 类型 说明
group_id INTEGER 群 ID
user_id INTEGER 用户 ID
role TEXT owner/admin/member
CREATE TABLE group_members (
    group_id INTEGER,
    user_id INTEGER,
    role TEXT CHECK(role IN ('owner', 'admin', 'member')) DEFAULT 'member',
    FOREIGN KEY (group_id) REFERENCES groups(group_id),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

3. 通信协议(TCP)

请添加图片描述

🔹 3.1 数据包格式(JSON)

{
   
    "type": "login",
    "username": "Alice",
    "password": "123456"
}

🔹 3.2 主要消息类型

操作 type 值 附加字段
登录 “login” username, password
注册 “register” username, password
私聊 “private_chat” from, to, message
群聊 “group_chat” group_id, from, message
添加好友 “add_friend” from, to
删除好友 “delete_friend” from, to

4. 服务器端实现

🔹 4.1 服务器初始化

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>

#define PORT 8080
#define MAX_CLIENTS 100

void *handle_client(void *sockfd) {
   
    int client_sock = *(int *)sockfd;
    char buffer[1024];

    while (1) {
   
        memset(buffer, 0, sizeof(buffer));
        int bytes = recv(client_sock, buffer, sizeof(buffer), 0);
        if (bytes <= 0) {
   
            printf("客户端断开连接\n");
            break;
        }
        printf("收到消息: %s\n", buffer);
        send(client_sock, "消息收到", strlen("消息收到"), 0);
    }

    close(client_sock);
    return NULL;
}

int main() {
   
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_size = sizeof(client_addr);

    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
    listen(server_sock, MAX_CLIENTS);

    printf("服务器启动, 监听端口 %d...\n", PORT);

    while (1) {
   
        client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_size);
        printf("新客户端连接: %d\n", client_sock);

        pthread_t thread;
        pthread_create(&thread, NULL, handle_client, &client_sock);
        pthread_detach(thread);
    }

    close(server_sock);
    return 0;
}

5. 客户端实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080

int main() {
   
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr;

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

    connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));

    char buffer[1024];
    while (1) {
   
        printf("输入消息: ");
        fgets(buffer, sizeof(buffer), stdin);
        send(sock, buffer, strlen(buffer), 0);

        memset(buffer, 0, sizeof(buffer));
        recv(sock, buffer, sizeof(buffer), 0);
        printf("服务器: %s\n", buffer);
    }

    close(sock);
    return 0;
}

5. 线程池优化(使用 epoll 处理多个客户端)

#include <sys/epoll.h>

int epfd = epoll_create(1);
struct epoll_event event, events[MAX_CLIENTS];

event.events = EPOLLIN;
event.data.fd = server_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, server_sock, &event);

while (1) {
   
    int n = epoll_wait(epfd, events, MAX_CLIENTS, -1);
    for (int i = 0; i < n; i++) {
   
        if (events[i].data.fd == server_sock) {
   
            int client_sock = accept(server_sock, NULL, NULL);
            event.data.fd = client_sock;
            epoll_ctl(epfd, EPOLL_CTL_ADD, client_sock, &event);
        } else {
   
            char buffer[1024];
            recv(events[i].data.fd, buffer, sizeof(buffer), 0);
            printf("收到: %s\n", buffer);
        }
    }
}

以上为项目结构 和 模块化的编程思想,下面提供完整代码:

✅ 使用 TCP + JSON 进行消息传输;
✅ 基于 SQLite3 存储用户、好友、群聊信息;
✅ 服务器采用 多线程 + I/O 多路复用(epoll) 支持高并发。

客户端(client)

头文件集合

my.h

#ifndef __MY_H__
#define __MY_H__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<poll.h>
#include<stdbool.h>
#include<json/json.h>
#include<sqlite3.h>
#include<sys/time.h>
#include<signal.h>
#include<semaphore.h>
#include<pthread.h>
#include<errno.h>

typedef struct msg{
   
char usr_name[20];
char passwd[20];
char qq_group[20];
char buf[100];
int qq;
int cmd;
}msg_q,*msg_p;

extern void struct_init(msg_p* qt);
extern void json_init(msg_p * p);
extern const char * json_pack(msg_p p);
extern msg_p json_unpack(const char * buf1);
extern int user_insert(int fd);
extern int login_qq(int fd);
extern int add_friend(int fd);
extern int sql_into(msg_p qt);
extern int del_friend(int fd);
extern int sql_del(int qq);
extern int tuichu_qq(int fd);
extern int siliao_friend(int fd);
extern int group_fd(int fd);
extern int group_creat(msg_p qt);
extern int add_f_gp(int fd);
extern int table_show();
extern int fun1(void* arg,int col,char** str,char** name);
extern int qunliao(int fd);
extern int del_g_f(int fd);
extern int chakan();
extern int chakan_gf(int fd);
extern int qun_lib();

#endif

json.h

#ifndef _JSON_H_
#define _JSON_H_
#include <stdio.h>
#include <string.h>
#include <json/json.h>
#include <stdlib.h>

typedef struct msg{
   
    char usr_name[20];
    char passwd[20];
    char qq_group[20];
    char buf[100];
    int qq;
    int cmd;
}msg_q,*msg_p;

extern void json_init(msg_p * p);
extern const char *json_pack(msg_p p);
extern msg_p json_unpack( const char *buf1);

#endif
主函数

client.c

#include"my.h"
int fd;
extern int sdnum;
int main(int argc, char const *argv[])   //./client server_ip server_port
{
   
    if (argc!=3)
    {
   
		printf("usage : %s <server_ip> <server_port>\n",argv[0]);//传参:服务器ip + 端口号
		exit(1);
    } 

    msg_p qq;
    msg_p qq1;
    json_init(&qq);
    json_init(&qq1);
    const char* auf;
    char buf[521];
    fd=socket(AF_INET,SOCK_STREAM,0);
    if (fd<0)
    {
   
	perror("socket");
	exit(1);
    }

    int ret;
    struct sockaddr_in server_addr;
    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(atoi(argv[2]));
    server_addr.sin_addr.s_addr=inet_addr(argv[1]);
    ret=connect(fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    if (ret<0)
    {
   
	perror("connect");
	exit(1);
    }
    /* 
       fd_set myset;
       while(1)
       {
       FD_ZERO(&myset); 
       FD_SET(0,&myset);
       FD_SET(fd,&myset);

       select(fd+1, &myset, NULL,NULL,NULL);
       if(FD_ISSET(0,&myset)){*/
end:
while(1)
{
   
    fd_set myset;
    while(1)
    {
   
	FD_ZERO(&myset); 
	FD_SET(0,&myset);
	printf("-------------\n");
	printf("----1.注册---\n");
	printf("----2.登录---\n");
	printf("----3.退出---\n");
	printf("-------------\n");
	struct_init(&qq);
	printf("please chose:\n");
	select(fd+1, &myset, NULL,NULL,NULL);
	scanf("%d",&qq->cmd);
	if(FD_ISSET(0,&myset)){
   
	    switch(qq->cmd){
   
		case 1:
		    user_insert(fd);//注册
		    bzero(buf,sizeof(buf));
		    struct_init(&qq1);
		    recv(fd,buf,sizeof(buf),0);
		    qq1=json_unpack(buf);
		    if(qq1->cmd==1){
   
			printf("注册成功\n");
			printf("你的QQ号为:%d\n",qq1->qq);
		    }else
			printf("注册失败\n");
		    break;
		case 2:
		    login_qq(fd);//登录
		    bzero(buf,sizeof(buf));
		    struct_init(&qq1);
		    recv(fd,buf,sizeof(buf),0);
		    qq1=json_unpack(buf);
		    if(qq1->cmd==1){
   
			printf("正在登录...\n");
			sleep(2);
		    }else{
   
			printf("帐号或密码错误\n");
			break;
		    }
		    // menu();
		    while(1)
		    {
   
			fd_set myset;
			while(1)
			{
   
begin:
			    FD_ZERO(&myset); 
			    FD_SET(0,&myset);
			    FD_SET(fd,&myset);
			    int qq_num;
			    int i;
			    //sleep(5);
			    system("clear");
			    printf("4.添加好友\n");
			    printf("5.删除好友\n");
			    printf("6.与好友私聊\n");
			    printf("7.创建群聊\n");
			    printf("8.拉好友进群\n");
			    printf("9.开始群聊\n");
			    printf("10.查看我的好友\n");
			    printf("11.查看群中的好友\n");
			    printf("12.退出登录\n");
			    printf("请输入数字选择相应操作\n");
			    select(fd+1, &myset, NULL,NULL,NULL);
			    if(FD_ISSET(fd,&myset))
			    {
    
				do{
   
				bzero(buf,sizeof(buf));
				ret=recv(fd,buf,sizeof(buf),0);
				struct_init(&qq1);
				qq1=json_unpack(buf);			
				printf("%s\n",qq1->buf);
				if(qq1->cmd==1000)
				{
   
				goto begin;
				}
				}while(qq1->cmd!=0);
				sleep(3);
				break;
			    }
			    scanf("%d",&i);
			    if(FD_ISSET(0,&myset)){
   
				switch(i){
   
				    case 4:
					add_friend(fd);//添加好友
					sleep(2);
					break;
				    case 5:
					printf("请输入你要删除好友的QQ:");
					scanf("%d",&qq_num);
					//del_friend(fd);
					bzero(buf,sizeof(buf));
					struct_init(&qq1);
					qq1->cmd=5;
					qq1->qq=qq_num;
					auf=json_pack(qq1);
					send(fd,auf,strlen(auf),0);
					recv(fd,buf,sizeof(buf),0);
					qq1=json_unpack(buf);
					if(qq1->cmd==1)
					{
   
					    sql_del(qq_num);
					    printf("删除成功\n");
					    sleep(2);
					    break;
					

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

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

相关文章

力扣27.移除元素(双指针)

题目看起来很乱&#xff0c;实际上意思是&#xff1a;把数组中值不等于val的元素放在下标为0,1,2,3......&#xff0c;并且返回数组中值不等于val的元素的个数 方法一&#xff1a;直接判断覆盖 class Solution { public:int removeElement(vector<int>& nums, int…

VADv2: 基于矢量表征和概率规划的E2E架构

1. 写在前面 今天分享一篇自动驾驶领域的论文VADv2(End-to-End Vectorized Autonomous Driving via Probabilistic Planning), 基于矢量表征和概率规划的E2E架构,2024年2月份华中科技大和地平线合作的一篇文章, 在经典的端到端模型架构上作出了基于概率规划去输出规划轨迹的…

机器学习:强化学习的epsilon贪心算法

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是一种机器学习方法&#xff0c;旨在通过与环境交互&#xff0c;使智能体&#xff08;Agent&#xff09;学习如何采取最优行动&#xff0c;以最大化某种累积奖励。它与监督学习和无监督学习不同&#xff0c;强调试错…

计算机毕业设计SpringBoot+Vue.js基于JAVA语言的在线考试与学习交流网页平台(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

数据图表ScottPlot.WPF用法示例

目录 一、添加 NuGet 程序包&#xff08;5.0.47&#xff09; 二、MainWindow.xaml中添加引用 三、MainWindow.xaml.cs 具体使用代码 图表示例&#xff1a; 一、添加 NuGet 程序包&#xff08;5.0.47&#xff09; 二、MainWindow.xaml中添加引用 <Window x:Class"…

【第二十五周】:DeepPose:通过深度神经网络实现人体姿态估计

DeepPose 摘要Abstract文章信息引言DeepPose归一化网络结构初始网络&#xff08;粗略估计所有关节点位置&#xff09;精细化级联网络&#xff08;分别修正每个关节点的位置&#xff09; 疑问与解决代码实践总结 摘要 这篇博客介绍了DeepPose&#xff0c;这是首个基于深度神经网…

ARM Linux LCD上实时预览摄像头画面

文章目录 1、前言2、环境介绍3、步骤4、应用程序编写4.1、lcd初始化4.2、摄像头初始化4.3、jpeg解码4.4、开启摄像头4.5、完整的程序如下 5、测试5.1、编译应用程序5.2、运行应用程序 6、总结 1、前言 本次应用程序主要针对支持MJPEG格式输出的UVC摄像头。 2、环境介绍 rk35…

MacOS本地部署Deepseek,不联网也可以使用AI,保护隐私

苹果笔记本本地部署deepseek主要用到Ollama与open-webui 1. 安装Ollama “Ollama” 是一个轻量级的 AI 模型运行时环境&#xff08;runtime&#xff09;&#xff0c;旨在简化在本地部署和使用大语言模型&#xff08;LLM&#xff09;的过程。它由 Vicarious 公司开发&#xff…

Sqlserver安全篇之_启用TLS即配置SQL Server 数据库引擎以加密连接

官方文档 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/configure-sql-server-encryption?viewsql-server-ver16 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/manage-certificates?viewsql-server-ver15&pre…

创建一个MCP服务器,并在Cline中使用,增强自定义功能。

MCP介绍 MCP 是一个开放协议&#xff0c;它标准化了应用程序如何向LLMs提供上下文。可以将 MCP 视为 AI 应用程序的 USB-C 端口。正如 USB-C 提供了一种标准化的方法来将您的设备连接到各种外围设备和配件一样&#xff0c;MCP 提供了一种标准化的方法来将 AI 模型连接到不同的…

游戏引擎学习第131天

仓库:https://gitee.com/mrxiao_com/2d_game_3 运行游戏并识别我们的小问题 今天的工作重点是对游戏引擎进行架构优化&#xff0c;特别是针对渲染和多线程的部分。目前&#xff0c;我们的目标是让地面块在独立线程上进行渲染&#xff0c;以提高性能。在此过程中&#xff0c;我…

人大金仓国产数据库与PostgreSQL

一、简介 在前面项目中&#xff0c;我们使用若依前后端分离整合人大金仓&#xff0c;在后续开发过程中&#xff0c;我们经常因为各种”不适配“问题&#xff0c;但可以感觉得到大部分问题&#xff0c;将人大金仓视为postgreSQL就能去解决大部分问题。据了解&#xff0c;Kingba…

MacBook Pro使用FFmpeg捕获摄像头与麦克风推流音视频

FFmpeg查看macos系统音视频设备列表 ffmpeg -f avfoundation -list_devices true -i "" 使用摄像头及麦克风同时推送音频及视频流: ffmpeg -f avfoundation -pixel_format yuyv422 -framerate 30 -i "0:1" -c:v libx264 -preset ultrafast -b:v 1000k -…

APISIX Dashboard上的配置操作

文章目录 登录配置路由配置消费者创建后端服务项目配置上游再创建一个路由测试 登录 http://192.168.10.101:9000/user/login?redirect%2Fdashboard 根据docker 容器里的指定端口&#xff1a; 配置路由 通过apisix 的API管理接口来创建&#xff08;此路由&#xff0c;直接…

计算机毕业设计SpringBoot+Vue.js人力资源管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

腾讯云扩容记录

腾讯云扩容&#xff1a; sudo yum install -y cloud-utils-growpart 安装扩容工具 sudo file -s /dev/vda1 有数据 sudo LC_ALLen_US.UTF-8 growpart /dev/vda 1 sudo resize2fs /dev/vda1 df -Th 完毕 以下是对执行的命令的详细解释以及背后的原理&#xff1a; 1. 安装 cloud…

Cherry Studio + 火山引擎 构建个人AI智能知识库

&#x1f349;在信息化时代&#xff0c;个人知识库的构建对于提高工作效率、知识管理和信息提取尤为重要。尤其是当这些知识库能结合人工智能来智能化地整理、分类和管理数据时&#xff0c;效果更为显著。我最近尝试通过 Cherry Studio 和 火山引擎 来搭建个人智能知识库&#…

完美解锁便捷版!

视频文件的种类繁多&#xff0c;包括常见的格式如MP4、AVI、MOV、MKV等。随着视频技术的发展&#xff0c;新的编码格式如HEVC&#xff08;H.265&#xff09;和AV1也逐渐被广泛应用&#xff1b;视频文件通常会经过压缩&#xff0c;并且每种格式都有其独特的编码方式和特性&#…

JAVA SE 包装类和泛型

文章目录 &#x1f4d5;1. 包装类✏️1.1 基本数据类型和对应的包装类✏️1.2 装箱和拆箱✏️1.3 自动装箱和自动拆箱 &#x1f4d5;2. 泛型✏️2.1 泛型的语法✏️2.2 泛型类的使用✏️2.3 裸类型(Raw Type)✏️2.4 擦除机制✏️2.5 泛型的上界✏️2.6 泛型方法✏️2.7 通配符…

人工智能AI在汽车设计领域的应用探索

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…