深入理解Socket编程:构建简单的计算器服务器
一、Socket通信基础
1. Socket通信基本流程
服务器端流程:
-
创建Socket (
socket()
) -
绑定地址和端口 (
bind()
) -
监听连接 (
listen()
) -
接受连接 (
accept()
) -
数据通信 (
read()
/write()
) -
关闭连接 (
close()
)
客户端流程:
-
创建Socket (
socket()
) -
连接服务器 (
connect()
) -
数据通信 (
read()
/write()
) -
关闭连接 (
close()
)
2. 关键数据结构
struct sockaddr_in
用于存储IPv4地址信息:
struct sockaddr_in {short sin_family; // 地址族,如AF_INETunsigned short sin_port; // 端口号struct in_addr sin_addr; // IP地址char sin_zero[8]; // 填充字段 };struct in_addr {unsigned long s_addr; // 32位IPv4地址 };
二、服务器代码详解
1. 头文件引入
#include <stdio.h> // 标准输入输出 #include <stdlib.h> // 标准库函数 #include <string.h> // 字符串处理 #include <unistd.h> // POSIX系统调用 #include <sys/types.h> // 系统数据类型 #include <sys/socket.h> // Socket相关函数 #include <netinet/in.h> // Internet地址族
这些头文件提供了Socket编程所需的基本功能。
2. 错误处理函数
void error(const char *msg) {perror(msg); // 打印错误信息exit(1); // 异常退出 }
perror()
会根据全局变量errno
打印描述性错误信息。
3. 主函数结构
int main(int argc, char *argv[]) {if(argc < 2) {fprintf(stderr,"Port no not provided, Program terminated");exit(1);}// ... 其余代码 }
检查命令行参数,确保提供了端口号。
4. 变量声明
int sockfd, newsockfd, portno; char buffer[255]; struct sockaddr_in serv_addr, cli_addr; socklen_t clilen;
sockfd
: 监听Socket的文件描述符
newsockfd
: 与客户端通信的Socket文件描述符
serv_addr
/cli_addr
: 服务器/客户端地址信息
clilen
: 客户端地址结构长度
5. 创建Socket
sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) {error("Error opening Socket."); }
socket()
函数参数:
AF_INET
: IPv4地址族
SOCK_STREAM
: 面向连接的TCP Socket
0
: 默认协议(TCP)
6. 初始化服务器地址
bzero((char *)&serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]);serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno);
-
bzero()
: 清零内存区域 -
INADDR_ANY
: 监听所有网络接口 -
htons()
: 将端口号转换为网络字节序(大端)
7. 绑定Socket
if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)error("Binding Failed.");
bind()
将Socket与地址和端口绑定。
8. 监听连接
listen(sockfd,5);
listen()
开始监听连接,参数5
指定等待连接队列的最大长度。
9. 接受连接
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr,&clilen); if(newsockfd < 0)error("Error on Accept");
accept()
接受客户端连接,返回新的Socket文件描述符用于通信。
10. 计算器业务逻辑
int num1, num2, ans, choice,n; S: n = write(newsockfd,"Enter Number 1 : ",strlen("Enter Number 1")); if (n < 0) error("Error writing to socket"); read(newsockfd, &num1, sizeof(int)); printf("Client - Number 1 is : %d \n",num1);// ... 类似处理num2和choiceswitch (choice) { case 1:ans = num1 + num2;break; case 2:ans = num1 - num2;break; case 3:ans = num1 * num2;break; case 4:ans = num1 / num2;break; case 5:goto Q;break; }write(newsockfd,&ans,sizeof(int)); if(choice != 5)goto S;
这里实现了简单的计算器功能,使用goto
实现循环逻辑。
11. 关闭连接
Q: close(newsockfd); close(sockfd); return 0;
三、关键函数深度解析
1. socket()
int socket(int domain, int type, int protocol);
-
功能:创建通信端点
-
参数:
-
domain
: 通信域(AF_INET, AF_INET6等) -
type
: 通信语义(SOCK_STREAM, SOCK_DGRAM等) -
protocol
: 通常为0,表示默认协议
-
-
返回值:成功返回文件描述符,失败返回-1
2. bind()
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
-
功能:将Socket与地址绑定
-
参数:
-
sockfd
: Socket文件描述符 -
addr
: 指向地址结构的指针 -
addrlen
: 地址结构大小
-
-
返回值:成功返回0,失败返回-1
3. listen()
int listen(int sockfd, int backlog);
-
功能:开始监听连接请求
-
参数:
-
sockfd
: Socket文件描述符 -
backlog
: 等待连接队列的最大长度
-
-
返回值:成功返回0,失败返回-1
4. accept()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
-
功能:接受连接请求
-
参数:
-
addr
: 用于存储客户端地址 -
addrlen
: 地址结构大小
-
-
返回值:成功返回新的Socket文件描述符,失败返回-1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>void error(const char *msg)
{perror(msg);exit(1);
}
int main(int argc, char *argv[])
{if(argc < 2){fprintf(stderr,"Port no not provided, Program terminated");exit(1);}int sockfd, newsockfd, portno;char buffer[255];struct sockaddr_in serv_addr, cli_addr;socklen_t clilen;sockfd = socket(AF_INET, SOCK_STREAM, 0);if(sockfd < 0){error ("Error opening Socket.");}bzero((char *)&serv_addr, sizeof(serv_addr));portno = atoi(argv[1]);serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = INADDR_ANY;serv_addr.sin_port = htons(portno);if(bind(sockfd , (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)error("Binding Failed.");listen(sockfd,5);clilen = sizeof(cli_addr);newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr,&clilen);if(newsockfd < 0)error("Error on Accept");int num1, num2, ans, choice,n;S: n = write(newsockfd,"Enter Number 1 : ",strlen("Enter Number 1")); if (n < 0) error("Error writing to socket");read(newsockfd, &num1, sizeof(int));printf("Client - Number 1 is : %d \n",num1);n = write(newsockfd,"Enter Number 2 : ",strlen("Enter Number 2")); if (n < 0) error("Error writing to socket");read(newsockfd, &num2, sizeof(int));printf("Client - Number 2 is : %d \n",num2);n = write(newsockfd,"Enter your choice: \n1.Addition\n2.subtraction\n3.Multiplication\n4.Division\n5.Exit\n",strlen("Enter your choice: \n1.Addition\n2.subtraction\n3.Multiplication\n4.Division\n5.Exit\n"));if(n < 0) error("ERROR writing to socket");read(newsockfd, &choice, sizeof(int));printf("Client - choice is :%d\n",choice);switch (choice){case 1:ans = num1 + num2;break;case 2:ans = num1 - num2;break;case 3:ans = num1 * num2;break;case 4:ans = num1 / num2;break;case 5:goto Q;break;}write(newsockfd,&ans,sizeof(int));if(choice != 5)goto S;Q: close(newsockfd);close(sockfd);return 0;}
/*
filename server_ipaddress portnoargc[0] filename
argv[1] serve_ipaddress
argv[2] portno
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>void error(const char *msg)
{perror(msg);exit(0);
}
int main(int argc, char *argv[])
{int sockfd, portno, n;char buffer[256];struct sockaddr_in serv_addr;struct hostent *server;if (argc < 3){fprintf(stderr, "usage %s hostname port\n", argv[0]);exit(1);}portno = atoi(argv[2]);sockfd = socket(AF_INET, SOCK_STREAM, 0);if(sockfd < 0){error ("Error opening Socket.");}server = gethostbyname(argv[1]);if(server == NULL){fprintf(stderr, "Error,no such host");}bzero((char *)&serv_addr, sizeof(serv_addr));serv_addr.sin_family = AF_INET;bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);serv_addr.sin_port = htons(portno);if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){error("Connection Failed");}int num1, num2, choice, ans;S:bzero(buffer,256);n = read (sockfd, buffer, 255);if( n < 0 )error("ERROR reading from socket");printf("Server - %s\n",buffer);scanf("%d",&num1);write(sockfd, &num1,sizeof(int));bzero(buffer,256);n = read (sockfd, buffer, 255);if( n < 0 )error("ERROR reading from socket");printf("Server - %s\n",buffer);scanf("%d",&num2);write(sockfd, &num2,sizeof(int));bzero(buffer,256);n = read (sockfd, buffer, 255);if( n < 0 )error("ERROR reading from socket");printf("Server - %s\n",buffer);scanf("%d",&choice);write(sockfd, &choice,sizeof(int));if (choice == 5)goto Q;read(sockfd, &ans ,sizeof(int));printf("Server- The answer is :%d\n",ans);if(choice !=5)goto S;Q:printf("You have selected to exit.Exit Successful");close(sockfd);return 0;}
一、函数参数记忆框架(TCP Socket版)
1. 核心思维:"3W1H"模型
-
Where (地址相关):
sockaddr_in
,addrlen
-
What (数据相关):
buffer
,strlen
-
Which (标识符):
sockfd
,newsockfd
-
How (方式):
flags
(通常填0)
2. 函数参数速记表
函数 | 参数顺序助记口诀 | 必须记住的参数 |
---|---|---|
socket() | "家-门-钥匙" | AF_INET , SOCK_STREAM , 0 |
bind() | "门牌-地址本-地址长度" | sockfd , (struct sockaddr*)&serv_addr , sizeof(serv_addr) |
listen() | "门牌-候客室大小" | sockfd , 5 (backlog) |
accept() | "门牌-客户登记表-表长度" | sockfd , cli_addr , &clilen |
connect() | "门牌-目的地地址-地址长度" | sockfd , serv_addr , sizeof(serv_addr) |
read() /write() | "信箱-纸条-纸条大小" | newsockfd , buffer , sizeof(buffer) |
二、参数分类记忆法
1. 地址家族三件套
serv_addr.sin_family = AF_INET; // IPv4 serv_addr.sin_addr.s_addr = INADDR_ANY; // 所有IP serv_addr.sin_port = htons(portno); // 端口转换
-
记忆口诀:"家-门-方向牌"(family-address-port)
2. 类型转换四重奏
// 指针转换 (struct sockaddr*)&serv_addr// 字节序转换 htons() // host to network short htonl() // host to network long ntohs() // network to host short ntohl() // network to host long
-
记忆技巧:"h→n是出门,n→h是回家"
三、实战填参模板
1. 服务端标准流程
// 1. 创建socket(三固定参数) int sockfd = socket(AF_INET, SOCK_STREAM, 0);// 2. 绑定地址(结构体强制转换) bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));// 3. 接受连接(注意&clilen) accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
2. 客户端连接模板
connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
四、常见参数填错场景
错误场景 | 正确写法 | 记忆要点 |
---|---|---|
忘记地址结构体转换 | (struct sockaddr*)&serv_addr | "套外套"法则 |
传值 vs 传地址混淆 | &clilen 而不是 clilen | accept()要修改长度值 |
字节序未转换 | htons(portno) | 所有网络传输的数据都要转换 |
buffer大小计算错误 | read(fd, buf, sizeof(buf)) | 用sizeof而不是strlen |
五、调试技巧
-
参数检查清单:
-
所有网络字节序转换了吗?
-
地址结构体转换了吗?
-
长度参数传地址了吗?
-
错误处理都写了吗?
-
-
GDB调试命令:
bash
复制
(gdb) p serv_addr # 查看地址结构体 (gdb) p &serv_addr # 确认指针类型
六、类比记忆法
函数 | 现实类比 | 关键参数对应关系 |
---|---|---|
socket() | 买手机 | 手机类型=AF_INET |
bind() | 办手机卡 | 电话号码=portno |
listen() | 开机 | 最大未接来电=backlog |
accept() | 接听来电 | 来电显示=cli_addr |
connect() | 拨打电话 | 对方号码=serv_addr |
七、进阶记忆法(协议栈层次)
应用层:buffer数据 传输层:SOCK_STREAM/SOCK_DGRAM 网络层:AF_INET/AF_INET6 链路层:系统自动处理
记住:从上到下越来越底层,从下到上越来越抽象
相关文章:
深入理解Socket编程:构建简单的计算器服务器
一、Socket通信基础 1. Socket通信基本流程 服务器端流程: 创建Socket (socket()) 绑定地址和端口 (bind()) 监听连接 (listen()) 接受连接 (accept()) 数据通信 (read()/write()) 关闭连接 (close()) 客户端流程: 创建Socket (socket()) 连接…...
CPU狂飙900%,该怎么处理
首先,说明一下问题:CPU飙升200% 以上是生产容易发生的场景 场景:1:MySQL进程飙升900% 大家在使用MySQL过程,想必都有遇到过CPU突然过高,或者达到200%以上的情况。 数据库执行查询或数据修改操作时,系统需…...
C++继承完全指南:从语法到设计模式----图解原理+工业级代码示例+陷阱规避
🔮✨⚡️🌌 欢迎来到张有志的量子编程次元 🌌⚡️✨🔮 ▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ 🛸 核心探索舱 🛸 ⇩⇩⇩ 正在加载未来代码 ⇩⇩⇩ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔…...
使用Pholcus编写Go爬虫示例
想用Pholcus库来写一个Go的爬虫程序。首先,我得确认Pholcus的当前状态,因为之前听说过它可能已经不再维护了。不过用户可能还是需要基于这个库的示例,所以得先提供一个基本的框架。 首先,我应该回忆一下Pholcus的基本用法。Pholc…...
R Excel 文件:高效数据处理与可视化工具的完美结合
R Excel 文件:高效数据处理与可视化工具的完美结合 引言 在数据分析和处理领域,R语言因其强大的数据处理能力和丰富的可视化功能而备受青睐。而Excel作为最常用的电子表格软件,其广泛的应用也使得R与Excel的结合成为数据处理与可视化的理想…...
Python设计模式:适配模式
1. 适配模式(Adapter Pattern)详解 适配模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一种接口。适配模式使得原本由于接口不兼容而无法一起工作的类可以协同工作。换句话说…...
Python设计模式:策略模式
1. 什么是策略模式 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法的变化独立于使用算法的客户。换句话说,策略模式允许在运…...
Unity Internal-ScreenSpaceShadows 分析
一、代码结构 // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)Shader "Hidden/Internal-ScreenSpaceShadows" {Properties {_ShadowMapTexture ("", any) "" {} // 阴影贴图纹理&…...
nginx配置oss代理
工作中会有一些时候需要将图片,视频,音频等文件放到oss这种对象存储中进行存储,实现高性能的访问,这种情况叫做动静分离.这里只做了图片的配置,视频以及音频的配置是一样的. 以下是nginx.conf的配置信息,其中还有ssl的加密配置,以及后端服务器的代理模块配置,(这里不用的话可以…...
UML对象图
UML对象图 一、对象图核心概念 对象图(Object Diagram)描述的是系统在某一时刻对象(实例)的状态快照。它关注的是实际对象之间的实例关系,而不是类与类之间的静态结构。主要特点有: 对象(Ob…...
手机不同App音量自动调节软件
软件介绍 在日常使用手机的过程中,大家是不是经常会遇到在不同App之间切换时,需要频繁调整音量的情况呢?这样真的很不方便。而一款名为App Volume Control的软件就能很好地解决这个问题。 App Volume Control借助辅助功能服务,能…...
模板方法模式详解
模板方法模式详解及真实场景解决方案 推荐学习完策略模式和模板方法模式看这个案例: 策略与模板方法模式组合详解 模式定义 模板方法模式是一种行为设计模式,在父类中定义算法的骨架,允许子类在不改变算法结构的情况下重写特定步骤。核心思…...
基于SSM邮件收发管理系统(带源码、论文)
摘要 随着互联网技术的迅速发展和普及,网络通信已经成了人们离不开的通信手段。作为最早出现的网络通信方式还有世界上应用最为广泛的网络服务之一,电子邮件综合了电话通信和传统邮件的特点,具有传播速度快、价格低廉的优良特性。随着技术发…...
1990-2019年各地级市GDP数据
1990-2019年各地级市GDP数据 1、时间:1990-2019年 2、来源:城市年鉴 3、指标:行政区划代码、年份、省份、城市、经度、纬度、地区生产总值(万元) 4、范围:250地级市 5、指标解释:地区生产总值(Gross R…...
Scala相关知识学习总结5
1、多维数组 定义: val arr Array.ofDim[Double](3,4) 表示二维数组中有三个一维数组,每个一维数组有四个元素。 2、列表 List 不可变 List:默认不可变,可创建有序且可重复的列表,可使用:从右向左增加数据…...
【LangChain Agent 】详解,构建自主决策的 LLM 应用
🐇明明跟你说过:个人主页 🏅个人专栏:《深度探秘:AI界的007》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是 Lang Chain 2、什么是 Agent 二、LangChain …...
Scala基础知识7
一,可变数组和不可变数组的转换方法: 不可变数组转换为可变数组使用 toBuffer 函数. 可变数组转换为不可变数组使用 toArray 函数。 转换过程中原始数组不会发生变化,而是返回一个新的数组。 二,多维数组 使用 Array of 函数创建多维数组&am…...
vmware、centos: 快照、redis集群克隆、启动异常
问题描述 提示:这里描述项目中遇到的问题: 启动虚拟机报错: 指定的虚拟磁盘需要进行修复 打不开磁盘“D:\Virtual Machines\CentOS 7 64 位\CentOS 7 64 位-000001.vmdk”或它所依赖的某个快照磁盘。 模块“Disk”启动失败。 未能启动虚拟机…...
visual studio断点无法进入
问题背景: 使用VSQt进行编码,新增函数处断点无法进入。 问题排查 查看moc文件,汇编代码以及设置调试选项均不生效。 原因分析 之前无意间进行了排版优化,导致新增的代码未正常编译进去,通过“文件-> 高级保存选…...
CNVD-2025-06046:Google Chrome沙箱逃逸漏洞大揭秘与防护指南
CNVD-2025-06046:Google Chrome沙箱逃逸漏洞大揭秘与防护指南 前言:浏览器界的“越狱”事件 嘿,小伙伴们!今天咱们要聊的不是什么好莱坞大片,而是一出在浏览器世界里真实上演的“越狱”大戏!你没听错&…...
androd的XML页面 跳转 Compose Activity 卡顿问题
解决 XML 点击跳转到 Compose Activity 卡顿问题 当从 XML 布局的 Activity 跳转到 Compose Activity 时出现卡顿现象,这通常是由以下几个原因导致的: 可能的原因及解决方案 1. Compose 首次初始化开销 问题:Compose 框架首次初始化需要时…...
Springboot同时支持不同的数据库,Oracle,Postgresql
关键字 Java,Springboot,Vscode,支持多种数据库 背景环境 我在实际项目开发工程中遇到这样一个问题,用户 A 使用 Oracle 数据库,用户 B 使用 Postgresql 数据库,但是用户 AB 都使用我们的项目。所以项目…...
【计网】TCP协议的拥塞控制与流量控制
拥塞控制与流量控制的区别 流量控制 流量控制主要是控制端到端(发送端和接收端)之间的数据传输量,是局部的机制。 目的:防止发送方发送数据过快导致接收方来不及处理实现方式:通过滑动窗口机制,接收方通…...
Redis - 字典(Hash)结构和 rehash 机制
字典结构 Redis中的字典由dict.h/dict结构表示: typedef struct dict ( //类型特定函数dictType *type;//私有数据 void "privdata;//哈希表 dictht ht[2];//rehash索引 //当rehash不在进行时,值为-1 in trehashidx; } dict; Redis字典所使用的哈希表由dict.h/dictht 结…...
Redis 与 MongoDB 对比分析
Redis 与 MongoDB 对比分析 1. 核心定位 Redis:内存键值数据库,侧重高性能读写和低延迟,常用于缓存、实时分析、消息队列等场景。MongoDB:分布式文档型数据库,侧重灵活的数据模型和大规模数据存储,支持复…...
【愚公系列】《高效使用DeepSeek》058-选题策划
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
解决 Lettuce 在 Redis 集群模式下的故障转移问题
引言 在高可用系统中,故障转移是确保服务不中断的重要机制。当我们使用 Lettuce 作为 Redis 的 Java 客户端时,如何高效地处理故障转移成为一项关键任务。本篇文章将探讨如何在 Redis 集群模式下配置 Lettuce 以优化故障转移。 背景 在初期设置 Lettu…...
Vim搜索和替换
模式 命令模式 操作过程 键入/开始搜索,找到想要搜索的内容后直接回车,此时光标会从搜索框回到编辑器中。 之后可以 使用小写n跳到下一个符合条件的内容,使用大写N跳到上一个搜索的内容。也可以直接使用上下左右按钮调整光标位置。...
【探商宝】 Llama 4--技术突破与争议并存的开源多模态
核心亮点 混合专家架构(MoE)的全面应用 Llama 4 是 Meta 首个全系列采用 MoE 架构 的模型,通过稀疏激活机制显著提升效率。例如: Llama 4 Scout(中杯):16 位专家,17B 活跃参数&#…...
可发1区的超级创新思路(python 实现):一种轻量化的动态稀疏门控网络
首先声明,该模型为原创!原创!原创!且该思路还未有成果发表,感兴趣的小伙伴可以借鉴! 一、应用领域 视频异常检测、生成视频检测。 二、模型解析 该模型由1.关键帧动态选择机制、2.关键帧动态选择机制以及3.关键帧动态选择机制三大核心组件构成,形成端到端的视频异常…...
flink cdc的source数据流如何配置事件时间,如何设置时间语义,分配时间戳并生成水位线
在 Flink CDC 中为 Source 数据流配置事件时间需要结合时间语义设置、时间戳分配和水位线生成三个核心步骤。以下是具体配置方法及注意事项: 1. 设置时间语义 Flink 默认使用处理时间(Processing Time),需显式指定事件时间语义&a…...
Vue3:初识Vue,Vite服务器别名及其代理配置
一、创建一个Vue3项目 创建Vue3项目默认使用Vite作为现代的构建工具,以下指令本质也是通过下载create-vue来构建项目。 基于NodeJs版本大于等于18.3,使用命令行进行操作。 1、命令执行 npm create vuelatest输入项目名称 2、选择附加功能 选择要包含的功…...
医疗场景与事件驱动的高匹配颗粒度医疗智能体研发方向探析(代码版)
结合技术实现、应用场景与挑战展开分析: 一、医疗场景驱动的智能体核心方向 全场景覆盖的诊疗辅助医疗智能体系统编程方案 1.1、技术架构设计 #mermaid-svg-OKB0oAt38jXWNClG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#m…...
HTML5 浏览器兼容性:让旧浏览器也能拥抱 HTML5
在前端开发领域,HTML5 带来了一系列令人兴奋的新特性和功能,极大地提升了用户体验和开发效率。然而,由于互联网用户使用的浏览器版本千差万别,部分旧版本浏览器并不支持 HTML5,这给开发者带来了兼容性方面的挑战。不过…...
Kubernetes 集群搭建(三):使用dashboard用户界面(需要访问外网获取yaml)
(一)简介 K8s Dashboard是Kubernetes提供的一种基于Web的用户界面工具,用于可视化地管理和监控Kubernetes集群 主要功能: 资源查看与管理: 查看Kubernetes集群中的各种资源,如节点、Pod、服务、部署等。 对…...
【图像处理基石】什么是ISP色彩管理?
在ISP(Image Signal Processor,图像信号处理器)管线中,色彩管理是图像处理流程的核心环节,主要负责从传感器原始数据(RAW)到最终输出图像(如YUV、RGB或JPEG)的色彩转换、…...
金融维度下的公链价值重构:重塑财富新秩序
公链的引言: 众人对 Crypto、Token 的探讨热度居高不下。在此大背景下,我打算另辟蹊径,从金融维度重新剖析区块链分布式账本。那么,我们究竟该如何正确认知它?又该如何搭建起一套从金融视角出发的分析框架呢࿱…...
LeetCode算法题(Go语言实现)_34
题目 考虑一棵二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。 如果有两棵二叉树的叶值序列是相同,那么我们就认为它们是 叶相似 的。 如果给定的两个根结点分别为 root1 和 root2 的树是叶相似的,则返回 true&…...
# 项目部署指南:Flask、Gradio与Docker实现流程
Python项目部署指南:Flask、Gradio与Docker实践 1. 引言 在机器学习和Web开发中,将模型或应用部署为在线服务是关键一步。本文将介绍如何使用 Flask 和 Gradio 快速构建前端界面,并通过 Docker 容器化实现高效部署,涵盖完整流程图…...
2022第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(题解解析)
记录刷题的过程、感悟、题解。 希望能帮到,那些与我一同前行的,来自远方的朋友😉 大纲: 1、九进制转十进制-(解析)-简单的进制转化问题😄 2、顺子日期-(解析)-考察日期 3…...
UML之序列图的参与者与生命线
序列图是建模过程中必选的一种描述行为的手段,它展示在某些有用的行为中元素之间的消息交换和相互作用。交互是构成行为的一个单元;这些元素必须是可连接元素,通常将这些可连接元素称为交互中的参与者(Participants)。…...
基于Python Flask快速构建网络安全工具资源库的Web应用实践
引言 在网络安全领域,信息收集(OSINT)是渗透测试、漏洞挖掘和威胁分析的关键环节。然而,面对海量工具和分散的技术文档,安全研究人员常需耗费大量时间查找和比对工具信息。本文将介绍如何利用 Python Flask HTML 技…...
xv6-labs-2024 lab1
lab-1 注:实验环境在我的汇编随手记的末尾部分有搭建教程。 0.前置 第零章 xv6为我们提供了多种系统调用,其中,exec将从某个文件里读取内存镜像(这确实是一个好的说法),并且将其替换到调用它的内存空间,也就是这个…...
HTTP Form v.s. Flask-WTF Form v.s. Bootstrap Form
在Flask-WTF和Bootstrap 的Form创建中,添加了页面显示Flash Messages。 相比Flask_WTF, Bootstrap用 render_form(form)渲染样式,自动带错误提示,不需要像Flask_WTF那样手写 for error in ... 。 项目结构: register_app/ ├── HTTP_Form_App.py ├── FlaskWTF_Form…...
Linux网络编程——https的协议及其加密解密方式
目录 一、前言 https协议 常见的加密方式 1、对称加密 2、非对称加密 3、数字签名 1. 只用对称加密 2、只用单一的非对称加密 3、双方都使用非对称加密 4、非对称加密对称加密 证书 证书颁发流程 服务器与客户端的证书验证流程 5、证书非对称加密对称加密 前言 上一…...
Node.js 下载与安装(图文)
下载 官网:【直达:https://nodejs.org/en/】。 点击【Download】,选择【版本,系统】。点击【Windows Installer(.msi)】。 安装 双击【.msi文件】,选择【安装路径】,也可以一直【下一步】。 查看版本 …...
3.31-4.06 Web3 游戏周报:Pebble 玩家留存率登顶,Treasure DAO 面临重组危机
回顾上周的区块链游戏概况,查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【3.31–4.06】Web3 游戏行业动态 链游生态系统 Treasure DAO 因财务危机面临重组,将终止游戏运营和 Treasure Chain3A 链游 Shrapnel 开发商 Neon Machine 深陷财务…...
echarts生成3D立体地图react组件
地图散点图效果: react项目中安装echarts、echarts-gl依赖: npm install echarts echarts-gl 文件目录结构: 地图组件map目录下文件代码,点击散点图圆点触发事件handleCityClick: index.jsx: import { …...
Node.js 中处理 Excel 文件的最佳实践
在现代应用开发中,Excel 文件仍然是数据交换和存储的重要格式之一。在 Node.js 环境中,处理 Excel 文件的需求日益增加。本文将介绍如何在 Node.js 中高效地处理 Excel 文件,涵盖工具选择、基本操作和最佳实践。 1. 选择合适的库 在 Node.js…...
解决Ubuntu系统鼠标不流畅的问题
电脑是联想的台式组装机,安装ubuntu系统(不管是16、18、20、22)后,鼠标都不流畅。最近几天想解决这个问题,于是怀疑到了显卡驱动上。怀疑之前一直用的是集成显卡,而不是独立显卡,毕竟2060的显卡…...