feat:init
This commit is contained in:
commit
fa6f029eea
47
.bash_history
Normal file
47
.bash_history
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
ls
|
||||||
|
。ã€./linux
|
||||||
|
./linux
|
||||||
|
exit
|
||||||
|
ls
|
||||||
|
./init.sh
|
||||||
|
exit
|
||||||
|
gcc -o linux linux.c -lpthread -lssl -lcrypto
|
||||||
|
gcc -o linux linux.c -lpthread -lssl -lcrypto
|
||||||
|
gcc -o linux linux.c -lpthread -lssl -lcrypto
|
||||||
|
./linux
|
||||||
|
openssl ecparam -name SM2 -genkey -noout -out sm2_key.pem
|
||||||
|
openssl ec -in sm2_key.pem -pubout -out sm2_pub.pem
|
||||||
|
ll
|
||||||
|
ls
|
||||||
|
cat sm2_key.pem
|
||||||
|
ls
|
||||||
|
exit
|
||||||
|
gcc client.c -o client -lssl -lcrypto
|
||||||
|
openssl version
|
||||||
|
openssl-devel version
|
||||||
|
yum install -y openssl-devel
|
||||||
|
find /usr/include/openssl -name sm4.h
|
||||||
|
which openssl
|
||||||
|
find /usr/bin/openssl -name sm4.h
|
||||||
|
find /usr/bin/openssl/ -name sm4.h
|
||||||
|
cd /usr/bin/openssl
|
||||||
|
wget https://www.openssl.org/source/openssl-3.0.12.tar.gz
|
||||||
|
yum install wget
|
||||||
|
wget https://www.openssl.org/source/openssl-3.0.12.tar.gz
|
||||||
|
find / -name sm4.h
|
||||||
|
cd /
|
||||||
|
ls
|
||||||
|
find / -name sm4.h
|
||||||
|
cd /usr/include/
|
||||||
|
ll
|
||||||
|
ls
|
||||||
|
ls
|
||||||
|
ls -l
|
||||||
|
exit
|
||||||
|
ll
|
||||||
|
alias ll 'ls -l'
|
||||||
|
alias 'll' 'ls -l'
|
||||||
|
alias ll 'ls -l'
|
||||||
|
alias 'ls -l' ll
|
||||||
|
gcc -o server server.c -lpthread -L/usr/local/lib -I/usr/local/include -lgmssl -lpthread -lz
|
||||||
|
exit
|
19
.vscode/c_cpp_properties.json
vendored
Normal file
19
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Mac",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"macFrameworkPath": [
|
||||||
|
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
|
||||||
|
],
|
||||||
|
"compilerPath": "/usr/bin/clang",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "macos-clang-arm64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"sm4.h": "c",
|
||||||
|
"fcntl.h": "c",
|
||||||
|
"stat.h": "c",
|
||||||
|
"socket.h": "c",
|
||||||
|
"in.h": "c",
|
||||||
|
"rand.h": "c",
|
||||||
|
"inet.h": "c",
|
||||||
|
"unistd.h": "c"
|
||||||
|
}
|
||||||
|
}
|
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
FROM openeuler/openeuler:latest
|
||||||
|
|
||||||
|
LABEL author="Tomyee"
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
COPY ./GmSSL /root/GmSSL
|
||||||
|
|
||||||
|
RUN yum update -y \
|
||||||
|
&& yum install -y zlib zlib-devel gcc gcc-c++ make cmake \
|
||||||
|
&& cd /root/GmSSL \
|
||||||
|
&& mkdir build \
|
||||||
|
&& cd build \
|
||||||
|
&& cmake .. \
|
||||||
|
&& make \
|
||||||
|
&& make test \
|
||||||
|
&& make test \
|
||||||
|
&& sudo make install
|
||||||
|
|
||||||
|
# 默认执行脚本
|
||||||
|
CMD ["/bin/bash"]
|
1
GmSSL
Submodule
1
GmSSL
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 34fa519dc0f94a9a3995d9daf09c84cdac37abd8
|
1791
GmSSL 3.1.1 Linux.sh
Executable file
1791
GmSSL 3.1.1 Linux.sh
Executable file
File diff suppressed because it is too large
Load Diff
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
- 开发环境
|
||||||
|
> macOS + Docker 部署 openeuler/openeuler(详细见 Dockefile 以及 docker-compose.yml)
|
||||||
|
|
||||||
|
技术:
|
||||||
|
|
||||||
|
~~~bash
|
||||||
|
gcc -o server server.c -lpthread -L/usr/local/lib -I/usr/local/include -lgmssl -lz
|
||||||
|
gcc -o client client.c
|
||||||
|
~~~
|
175
client.c
Normal file
175
client.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
// client.c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define PORT 8001
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
void upload_file(int client_socket)
|
||||||
|
{
|
||||||
|
char file_name[BUFFER_SIZE];
|
||||||
|
char file_content[BUFFER_SIZE];
|
||||||
|
|
||||||
|
// 用户输入文件名
|
||||||
|
printf("输入要创建的文件名(不带路径): ");
|
||||||
|
scanf("%s", file_name);
|
||||||
|
|
||||||
|
// 用户输入文件内容
|
||||||
|
printf("输入文件内容(输入完毕后按回车结束):\n");
|
||||||
|
getchar(); // 清除上一次输入的换行符
|
||||||
|
fgets(file_content, BUFFER_SIZE, stdin);
|
||||||
|
|
||||||
|
// 以file_name为文件名创建文件并将输入内容写入文件
|
||||||
|
FILE *plain_file = fopen(file_name, "w");
|
||||||
|
if (!plain_file)
|
||||||
|
{
|
||||||
|
perror("文件创建失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(plain_file, "%s", file_content);
|
||||||
|
fclose(plain_file);
|
||||||
|
printf("文件创建成功,开始上传。\n");
|
||||||
|
|
||||||
|
// 发送文件名到服务器
|
||||||
|
send(client_socket, file_name, strlen(file_name), 0);
|
||||||
|
// 等待服务器确认收到文件名
|
||||||
|
char ack[BUFFER_SIZE] = {0};
|
||||||
|
read(client_socket, ack, BUFFER_SIZE);
|
||||||
|
if (strcmp(ack, "ACK") == 0)
|
||||||
|
{
|
||||||
|
printf("服务端确认文件名。\n");
|
||||||
|
}else{
|
||||||
|
printf("服务端未确认文件名。\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 发送文件内容到服务器
|
||||||
|
FILE *file = fopen(file_name, "rb");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
perror("文件打开失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
// 分块读取文件内容并发送到服务端
|
||||||
|
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0)
|
||||||
|
{
|
||||||
|
if (send(client_socket, buffer, bytes_read, 0) < 0)
|
||||||
|
{
|
||||||
|
perror("发送文件数据失败");
|
||||||
|
fclose(file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
// 发送文件传输结束标志
|
||||||
|
send(client_socket, "EOF", strlen("EOF"), 0);
|
||||||
|
printf("文件已上传。\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void download_file(int client_socket)
|
||||||
|
{
|
||||||
|
char output_file_name[BUFFER_SIZE];
|
||||||
|
char file_name[BUFFER_SIZE];
|
||||||
|
|
||||||
|
printf("输入要下载的文件名(不带路径): ");
|
||||||
|
scanf("%s", file_name);
|
||||||
|
|
||||||
|
// 发送下载请求到服务器
|
||||||
|
send(client_socket, "DOWNLOAD", strlen("DOWNLOAD"), 0);
|
||||||
|
send(client_socket, file_name, strlen(file_name), 0);
|
||||||
|
// 等待服务端准备完成的信号
|
||||||
|
char ack[BUFFER_SIZE] = {0};
|
||||||
|
int ack_read = read(client_socket, ack, BUFFER_SIZE);
|
||||||
|
if (ack_read > 0 && strcmp(ack, "READY") == 0)
|
||||||
|
{
|
||||||
|
printf("服务端已准备好,开始接收文件...\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("服务端未准备好或通信失败。\n");
|
||||||
|
close(client_socket);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 创建输出文件
|
||||||
|
sprintf(output_file_name, "%s_output.txt", file_name);
|
||||||
|
FILE *output = fopen(output_file_name, "wb");
|
||||||
|
if (!output)
|
||||||
|
{
|
||||||
|
perror("文件打开失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 接收文件数据
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
while ((bytes_read = read(client_socket, buffer, BUFFER_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
fwrite(buffer, 1, bytes_read, output);
|
||||||
|
}
|
||||||
|
fclose(output);
|
||||||
|
printf("文件已下载,保存在 %s 中。\n", output_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int client_socket;
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
|
||||||
|
// 创建客户端 socket
|
||||||
|
client_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (client_socket == -1)
|
||||||
|
{
|
||||||
|
perror("客户端 socket 创建失败");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置服务器地址
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 修改为服务器的实际IP地址
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
// 连接服务器
|
||||||
|
if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
|
||||||
|
{
|
||||||
|
perror("连接服务器失败");
|
||||||
|
close(client_socket);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 连接成功后打印确认消息
|
||||||
|
printf("连接服务器成功。\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char command[10];
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
printf("请输入命令 (UPLOAD/DOWNLOAD/EXIT): ");
|
||||||
|
scanf("%s", command);
|
||||||
|
|
||||||
|
if (strcmp(command, "UPLOAD") == 0)
|
||||||
|
{
|
||||||
|
upload_file(client_socket);
|
||||||
|
}
|
||||||
|
else if (strcmp(command, "DOWNLOAD") == 0)
|
||||||
|
{
|
||||||
|
download_file(client_socket);
|
||||||
|
}
|
||||||
|
else if (strcmp(command, "EXIT") == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("未知命令,请重试。\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(client_socket);
|
||||||
|
return 0;
|
||||||
|
}
|
1
files/20241217102043/test.enc
Normal file
1
files/20241217102043/test.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
sÓÍQÒ÷W%ƒ¡ßKó)$ýí´o&TI…ùÍwɽ5·m=Öýø3oØßß𯚑g
|
BIN
files/20241217102043/test.gz
Normal file
BIN
files/20241217102043/test.gz
Normal file
Binary file not shown.
2
files/20241217102043/test.txt
Normal file
2
files/20241217102043/test.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOFDOWNLOADtest
|
0
files/20241217102536/123.txt
Normal file
0
files/20241217102536/123.txt
Normal file
1
files/20241217103021/321.enc
Normal file
1
files/20241217103021/321.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
№в;;ўXµg:•ЇL@зA
|
BIN
files/20241217103021/321.gz
Normal file
BIN
files/20241217103021/321.gz
Normal file
Binary file not shown.
1
files/20241217103021/321.txt
Normal file
1
files/20241217103021/321.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
321
|
2
files/20241217103853/test.txt
Normal file
2
files/20241217103853/test.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOF
|
0
files/20241217104148/123.txt
Normal file
0
files/20241217104148/123.txt
Normal file
27
init.sh
Executable file
27
init.sh
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 更新软件包
|
||||||
|
echo "更新软件包..."
|
||||||
|
yum update -y
|
||||||
|
|
||||||
|
# 安装编译工具和库
|
||||||
|
echo "安装必要的工具和库..."
|
||||||
|
yum groupinstall "Development Tools" -y
|
||||||
|
yum install -y openssl openssl-devel
|
||||||
|
yum install -y zlib zlib-devel
|
||||||
|
openssl ecparam -name SM2 -genkey -noout -out sm2_key.pem
|
||||||
|
openssl ec -in sm2_key.pem -pubout -out sm2_pub.pem
|
||||||
|
|
||||||
|
# 编译程序
|
||||||
|
echo "开始编译程序..."
|
||||||
|
gcc -o linux linux.c -lpthread -lssl -lcrypto -lgmssl
|
||||||
|
|
||||||
|
# 显示编译结果
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "编译成功,生成可执行文件 'linux'"
|
||||||
|
else
|
||||||
|
echo "编译失败,请检查代码"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 保持容器运行
|
||||||
|
echo "容器初始化完成,进入交互模式..."
|
||||||
|
exec /bin/bash
|
239
linux.c
Normal file
239
linux.c
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
// 线程、信号量全局变量
|
||||||
|
pthread_t thread1, thread2;
|
||||||
|
sem_t semaphore;
|
||||||
|
|
||||||
|
// 消息队列结构
|
||||||
|
struct message {
|
||||||
|
long mtype;
|
||||||
|
char mtext[100];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 函数声明
|
||||||
|
void file_system_demo();
|
||||||
|
void thread_control_demo();
|
||||||
|
void process_communication_demo();
|
||||||
|
void socket_communication_demo();
|
||||||
|
void encryption_demo();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int choice;
|
||||||
|
while (1) {
|
||||||
|
printf("\n请选择要演示的功能模块:\n");
|
||||||
|
printf("1. 文件系统操作\n");
|
||||||
|
printf("2. 线程控制与信号量\n");
|
||||||
|
printf("3. 进程间通信\n");
|
||||||
|
printf("4. Socket通信\n");
|
||||||
|
printf("5. 加密解密与哈希\n");
|
||||||
|
printf("0. 退出\n");
|
||||||
|
printf("输入选择:");
|
||||||
|
scanf("%d", &choice);
|
||||||
|
|
||||||
|
switch (choice) {
|
||||||
|
case 1:
|
||||||
|
file_system_demo();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
thread_control_demo();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
process_communication_demo();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
socket_communication_demo();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
encryption_demo();
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
printf("退出程序。\n");
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
printf("无效选择,请重试。\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//文件系统操作
|
||||||
|
void file_system_demo() {
|
||||||
|
const char *filename = "testfile.txt";
|
||||||
|
const char *data = "这是一个文件系统操作的测试文件。\n";
|
||||||
|
|
||||||
|
// 创建文件并写入数据
|
||||||
|
int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
||||||
|
if (fd == -1) {
|
||||||
|
perror("创建文件失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write(fd, data, strlen(data));
|
||||||
|
close(fd);
|
||||||
|
printf("文件已创建并写入数据。\n");
|
||||||
|
|
||||||
|
// 读取文件数据
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
perror("打开文件失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char buffer[256];
|
||||||
|
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
|
||||||
|
if (bytes_read > 0) {
|
||||||
|
buffer[bytes_read] = '\0';
|
||||||
|
printf("文件内容:%s", buffer);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
// 删除文件
|
||||||
|
if (remove(filename) == 0) {
|
||||||
|
printf("文件已删除。\n");
|
||||||
|
} else {
|
||||||
|
perror("删除文件失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//线程控制与信号量
|
||||||
|
void *thread_function(void *arg) {
|
||||||
|
sem_wait(&semaphore);
|
||||||
|
printf("线程 %d: 信号量已获取。\n", *(int *)arg);
|
||||||
|
sleep(2);
|
||||||
|
printf("线程 %d: 任务完成,释放信号量。\n", *(int *)arg);
|
||||||
|
sem_post(&semaphore);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_control_demo() {
|
||||||
|
sem_init(&semaphore, 0, 1);
|
||||||
|
int id1 = 1, id2 = 2;
|
||||||
|
|
||||||
|
pthread_create(&thread1, NULL, thread_function, &id1);
|
||||||
|
pthread_create(&thread2, NULL, thread_function, &id2);
|
||||||
|
|
||||||
|
pthread_join(thread1, NULL);
|
||||||
|
pthread_join(thread2, NULL);
|
||||||
|
|
||||||
|
sem_destroy(&semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
//进程间通信 (消息队列)
|
||||||
|
#define PORT 8080
|
||||||
|
#define BUFFER_SIZE 256
|
||||||
|
void process_communication_demo() {
|
||||||
|
key_t key = ftok("msgqueue", 65);
|
||||||
|
int msgid = msgget(key, 0666 | IPC_CREAT);
|
||||||
|
if (msgid == -1) {
|
||||||
|
perror("创建消息队列失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct message msg;
|
||||||
|
msg.mtype = 1;
|
||||||
|
strcpy(msg.mtext, "来自进程间通信的消息!");
|
||||||
|
|
||||||
|
if (msgsnd(msgid, &msg, sizeof(msg.mtext), 0) == -1) {
|
||||||
|
perror("发送消息失败");
|
||||||
|
} else {
|
||||||
|
printf("消息已发送:%s\n", msg.mtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0) == -1) {
|
||||||
|
perror("接收消息失败");
|
||||||
|
} else {
|
||||||
|
printf("接收到消息:%s\n", msg.mtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
msgctl(msgid, IPC_RMID, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Socket通信
|
||||||
|
void socket_communication_demo() {
|
||||||
|
int server_fd, client_fd;
|
||||||
|
struct sockaddr_in server_addr, client_addr;
|
||||||
|
socklen_t client_addr_len = sizeof(client_addr);
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
// 创建套接字
|
||||||
|
server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server_fd == -1) {
|
||||||
|
perror("创建Socket失败");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配置服务器地址
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
// 绑定地址
|
||||||
|
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||||||
|
perror("绑定失败");
|
||||||
|
close(server_fd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始监听
|
||||||
|
if (listen(server_fd, 5) == -1) {
|
||||||
|
perror("监听失败");
|
||||||
|
close(server_fd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("服务器已启动,等待客户端连接...\n");
|
||||||
|
|
||||||
|
// 接受客户端连接
|
||||||
|
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
|
||||||
|
if (client_fd == -1) {
|
||||||
|
perror("接受连接失败");
|
||||||
|
close(server_fd);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("客户端已连接。\n");
|
||||||
|
|
||||||
|
// 接收消息
|
||||||
|
ssize_t bytes_received = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);
|
||||||
|
if (bytes_received > 0) {
|
||||||
|
buffer[bytes_received] = '\0';
|
||||||
|
printf("收到客户端消息:%s\n", buffer);
|
||||||
|
|
||||||
|
// 发送回应
|
||||||
|
const char *response = "Hello from server!";
|
||||||
|
send(client_fd, response, strlen(response), 0);
|
||||||
|
printf("回应已发送。\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭套接字
|
||||||
|
close(client_fd);
|
||||||
|
close(server_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//加密解密与哈希
|
||||||
|
void encryption_demo() {
|
||||||
|
const char *plaintext = "这是需要加密的文本。";
|
||||||
|
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||||
|
SHA256((unsigned char *)plaintext, strlen(plaintext), hash);
|
||||||
|
|
||||||
|
printf("SHA-256 哈希值:");
|
||||||
|
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
|
||||||
|
printf("%02x", hash[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
437
server.c
Normal file
437
server.c
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
// server.c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <gmssl/sm4.h>
|
||||||
|
#include <gmssl/rand.h>
|
||||||
|
#include <dispatch/dispatch.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define PORT 8001
|
||||||
|
#define MAX_CLIENTS 5
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
// 将信号量定义为全局变量
|
||||||
|
dispatch_semaphore_t semaphore;
|
||||||
|
int log_pipe[2]; // 日志记录的管道
|
||||||
|
|
||||||
|
// 生成时间戳目录
|
||||||
|
void create_timestamp_dir(char *dir_name)
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm *t = localtime(&now);
|
||||||
|
// t->tm_year:从 1900 年开始的年数,因此需要加上 1900 得到完整的年份。
|
||||||
|
// t->tm_mon:从 0 开始的月份(0 表示 1 月),因此需要加上 1 得到实际的月份。
|
||||||
|
// t->tm_mday:月份中的日期。
|
||||||
|
// t->tm_hour:小时。
|
||||||
|
// t->tm_min:分钟。
|
||||||
|
// t->tm_sec:秒。
|
||||||
|
sprintf(dir_name, "./files/%04d%02d%02d%02d%02d%02d",
|
||||||
|
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||||
|
t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
|
mkdir("./files", 0777);
|
||||||
|
mkdir(dir_name, 0777);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录日志
|
||||||
|
void log_operation(const char *message)
|
||||||
|
{
|
||||||
|
write(log_pipe[1], message, strlen(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件压缩
|
||||||
|
int compress_file(const char *src, const char *dest)
|
||||||
|
{
|
||||||
|
FILE *source = fopen(src, "rb");
|
||||||
|
gzFile dest_file = gzopen(dest, "wb");
|
||||||
|
if (!source || !dest_file)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, source)) > 0)
|
||||||
|
{
|
||||||
|
gzwrite(dest_file, buffer, bytes_read);
|
||||||
|
}
|
||||||
|
fclose(source);
|
||||||
|
gzclose(dest_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件解压
|
||||||
|
int decompress_file(const char *src, const char *dest)
|
||||||
|
{
|
||||||
|
gzFile source = gzopen(src, "rb");
|
||||||
|
FILE *dest_file = fopen(dest, "wb");
|
||||||
|
if (!source || !dest_file)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
while ((bytes_read = gzread(source, buffer, BUFFER_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
fwrite(buffer, 1, bytes_read, dest_file);
|
||||||
|
}
|
||||||
|
gzclose(source);
|
||||||
|
fclose(dest_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密文件方法
|
||||||
|
int sm4_cbc_padding_encrypt_file(const char *input_file, const char *output_file, const uint8_t *key, const uint8_t *iv)
|
||||||
|
{
|
||||||
|
SM4_KEY enc_key;
|
||||||
|
sm4_set_encrypt_key(&enc_key, key); // 设置加密密钥
|
||||||
|
|
||||||
|
FILE *in_file = fopen(input_file, "rb");
|
||||||
|
FILE *out_file = fopen(output_file, "wb");
|
||||||
|
if (!in_file || !out_file)
|
||||||
|
{
|
||||||
|
perror("文件打开失败");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t input_block[SM4_BLOCK_SIZE];
|
||||||
|
uint8_t output_block[SM4_BLOCK_SIZE + SM4_BLOCK_SIZE]; // 加密后可能需要填充
|
||||||
|
|
||||||
|
size_t bytes_read, outlen;
|
||||||
|
while ((bytes_read = fread(input_block, 1, SM4_BLOCK_SIZE, in_file)) > 0)
|
||||||
|
{
|
||||||
|
if (feof(in_file))
|
||||||
|
{
|
||||||
|
// 最后一块,带填充加密
|
||||||
|
if (sm4_cbc_padding_encrypt(&enc_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "加密失败。\n");
|
||||||
|
fclose(in_file);
|
||||||
|
fclose(out_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 中间块,不需要填充
|
||||||
|
if (sm4_cbc_padding_encrypt(&enc_key, iv, input_block, SM4_BLOCK_SIZE, output_block, &outlen) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "加密失败。\n");
|
||||||
|
fclose(in_file);
|
||||||
|
fclose(out_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fwrite(output_block, 1, outlen, out_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in_file);
|
||||||
|
fclose(out_file);
|
||||||
|
return 1; // 成功
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密文件方法
|
||||||
|
int sm4_cbc_padding_decrypt_file(const char *input_file, const char *output_file, const uint8_t *key, const uint8_t *iv)
|
||||||
|
{
|
||||||
|
SM4_KEY dec_key;
|
||||||
|
sm4_set_decrypt_key(&dec_key, key); // 设置解密密钥
|
||||||
|
|
||||||
|
FILE *in_file = fopen(input_file, "rb");
|
||||||
|
FILE *out_file = fopen(output_file, "wb");
|
||||||
|
if (!in_file || !out_file)
|
||||||
|
{
|
||||||
|
perror("文件打开失败");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t input_block[SM4_BLOCK_SIZE + SM4_BLOCK_SIZE]; // 假设有填充
|
||||||
|
uint8_t output_block[SM4_BLOCK_SIZE];
|
||||||
|
size_t bytes_read, outlen;
|
||||||
|
|
||||||
|
while ((bytes_read = fread(input_block, 1, sizeof(input_block), in_file)) > 0)
|
||||||
|
{
|
||||||
|
if (feof(in_file))
|
||||||
|
{
|
||||||
|
// 最后一块,带填充解密
|
||||||
|
if (sm4_cbc_padding_decrypt(&dec_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "解密失败。\n");
|
||||||
|
fclose(in_file);
|
||||||
|
fclose(out_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 中间块,不需要处理填充
|
||||||
|
if (sm4_cbc_padding_decrypt(&dec_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "解密失败。\n");
|
||||||
|
fclose(in_file);
|
||||||
|
fclose(out_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fwrite(output_block, 1, outlen, out_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in_file);
|
||||||
|
fclose(out_file);
|
||||||
|
return 1; // 成功
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客户端处理线程
|
||||||
|
void *client_handler(void *arg)
|
||||||
|
{
|
||||||
|
int client_socket = *(int *)arg;
|
||||||
|
free(arg);
|
||||||
|
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
// 初始化缓冲区为 0
|
||||||
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
|
||||||
|
// 接收文件名
|
||||||
|
int bytes = read(client_socket, buffer, BUFFER_SIZE);
|
||||||
|
if (bytes <= 0)
|
||||||
|
{
|
||||||
|
perror("接收文件名失败");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buffer[bytes] = '\0'; // 确保以 NULL 结尾
|
||||||
|
char file_name[256];
|
||||||
|
snprintf(file_name, sizeof(file_name), "%s", buffer);
|
||||||
|
printf("接收文件名:%s\n", file_name);
|
||||||
|
// 发送 ACK 确认
|
||||||
|
send(client_socket, "ACK", strlen("ACK"), 0);
|
||||||
|
|
||||||
|
char origin_file_path[256], dir_name[128], file_path[256], compressed_file[256], decrypted_file[256];
|
||||||
|
// 先生成./files目录,再生成时间戳目录,调用 create_timestamp_dir 函数,生成一个基于时间戳的目录名称,并将其存储在 dir_name 中
|
||||||
|
create_timestamp_dir(dir_name);
|
||||||
|
|
||||||
|
// 根据传入的文件名以及时间戳拼接生成源文件路径、加密后的文件、压缩的文件、解密的文件路径
|
||||||
|
sprintf(origin_file_path, "%s/%s.txt", dir_name, buffer);
|
||||||
|
sprintf(file_path, "%s/%s.enc", dir_name, buffer);
|
||||||
|
sprintf(compressed_file, "%s/%s.gz", dir_name, buffer);
|
||||||
|
// sprintf(decrypted_file, sizeof(decrypted_file), "%s/%s_decrypted.txt", dir_name, buffer);
|
||||||
|
snprintf(decrypted_file, sizeof(decrypted_file), "%s/%s_decrypted.txt", dir_name, buffer);
|
||||||
|
printf("源文件路径%s\n加密后的文件%s\n压缩的文件%s\n解密的文件路径%s\n", origin_file_path, file_path, compressed_file, decrypted_file);
|
||||||
|
FILE *file = fopen(origin_file_path, "wb");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
perror("文件打开失败");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// 按块读取源文件内容并保存到origin_file_path
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int bytes = read(client_socket, buffer, BUFFER_SIZE);
|
||||||
|
if (bytes < 0)
|
||||||
|
{
|
||||||
|
perror("读取数据失败");
|
||||||
|
fclose(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// 检测是否接收到结束标志
|
||||||
|
if (strncmp(buffer, "EOF", 3) == 0)
|
||||||
|
break;
|
||||||
|
// 将数据写入文件
|
||||||
|
if (fwrite(buffer, 1, bytes, file) != bytes)
|
||||||
|
{
|
||||||
|
perror("写入文件失败");
|
||||||
|
fclose(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
log_operation("文件已接收。\n");
|
||||||
|
|
||||||
|
// 随机生成加密密钥和 IV
|
||||||
|
uint8_t key[SM4_KEY_SIZE];
|
||||||
|
if (rand_bytes(key, SM4_KEY_SIZE) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "随机密钥生成失败。\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uint8_t iv[SM4_BLOCK_SIZE];
|
||||||
|
if (rand_bytes(iv, SM4_BLOCK_SIZE) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "随机IV生成失败。\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印密钥和 IV
|
||||||
|
printf("随机生成的密钥: ");
|
||||||
|
for (size_t i = 0; i < SM4_KEY_SIZE; i++)
|
||||||
|
{
|
||||||
|
printf("%02X ", key[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("随机生成的IV: ");
|
||||||
|
for (size_t i = 0; i < SM4_BLOCK_SIZE; i++)
|
||||||
|
{
|
||||||
|
printf("%02X ", iv[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// 加密文件
|
||||||
|
printf("正在加密文件...\n");
|
||||||
|
sm4_cbc_padding_encrypt_file(origin_file_path, file_path, key, iv);
|
||||||
|
printf("文件加密完成。\n");
|
||||||
|
char log_message_file_path[BUFFER_SIZE];
|
||||||
|
sprintf(log_message_file_path, "文件已加密。加密文件保存路径为:%s\n", file_path);
|
||||||
|
log_operation(log_message_file_path);
|
||||||
|
// 压缩文件
|
||||||
|
printf("正在压缩被加密的文件...\n");
|
||||||
|
compress_file(file_path, compressed_file);
|
||||||
|
printf("文件压缩完成。\n");
|
||||||
|
|
||||||
|
// 删除加密文件
|
||||||
|
// remove(file_path);
|
||||||
|
char log_message_compressed_file[BUFFER_SIZE];
|
||||||
|
sprintf(log_message_compressed_file, "文件已加密。加密文件保存路径为:%s\n", compressed_file);
|
||||||
|
log_operation(log_message_compressed_file);
|
||||||
|
|
||||||
|
// 等待客户端请求
|
||||||
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
read(client_socket, buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
|
if (strcmp(buffer, "DOWNLOAD") == 0)
|
||||||
|
{
|
||||||
|
printf("接收到下载请求...\n");
|
||||||
|
|
||||||
|
// 读取文件名
|
||||||
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
read(client_socket, buffer, BUFFER_SIZE);
|
||||||
|
char requested_file[256];
|
||||||
|
snprintf(requested_file, sizeof(requested_file), "%s", buffer);
|
||||||
|
printf("客户端请求的文件名: %s\n", requested_file);
|
||||||
|
printf("接收到下载请求,正在解压缩文件...\n");
|
||||||
|
decompress_file(compressed_file, decrypted_file);
|
||||||
|
printf("文件解压缩完成。\n");
|
||||||
|
|
||||||
|
printf("正在解密文件...\n");
|
||||||
|
sm4_cbc_padding_decrypt_file(decrypted_file, decrypted_file, key, iv);
|
||||||
|
printf("文件解密完成。\n");
|
||||||
|
|
||||||
|
log_operation("文件已解压并解密,准备发送。\n");
|
||||||
|
// 向客户端发送 "READY" 信号
|
||||||
|
send(client_socket, "READY", strlen("READY"), 0);
|
||||||
|
|
||||||
|
// 发送解密后的文件
|
||||||
|
FILE *file_to_send = fopen(decrypted_file, "rb");
|
||||||
|
while (!feof(file_to_send))
|
||||||
|
{
|
||||||
|
int bytes_read = fread(buffer, 1, BUFFER_SIZE, file_to_send);
|
||||||
|
send(client_socket, buffer, bytes_read, 0);
|
||||||
|
}
|
||||||
|
fclose(file_to_send);
|
||||||
|
|
||||||
|
printf("文件发送完成。\n");
|
||||||
|
// 删除解密后的文件
|
||||||
|
// remove(decrypted_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭连接
|
||||||
|
close(client_socket);
|
||||||
|
dispatch_semaphore_signal(semaphore);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
int server_socket, client_socket;
|
||||||
|
struct sockaddr_in server_addr, client_addr;
|
||||||
|
socklen_t client_addr_len = sizeof(client_addr);
|
||||||
|
|
||||||
|
// 创建服务器 socket
|
||||||
|
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server_socket == -1)
|
||||||
|
{
|
||||||
|
perror("服务器 socket 创建失败");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置服务器地址
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
// 绑定服务器 socket
|
||||||
|
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
|
||||||
|
{
|
||||||
|
perror("绑定失败");
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始监听
|
||||||
|
if (listen(server_socket, MAX_CLIENTS) == -1)
|
||||||
|
{
|
||||||
|
perror("监听失败");
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化信号量
|
||||||
|
semaphore = dispatch_semaphore_create(MAX_CLIENTS);
|
||||||
|
if (semaphore == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "信号量创建失败\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 示例:客户端处理逻辑
|
||||||
|
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // 等待信号量
|
||||||
|
// printf("客户端进入,当前资源被占用\n");
|
||||||
|
|
||||||
|
// 创建管道
|
||||||
|
pipe(log_pipe);
|
||||||
|
if (fork() == 0) // 日志进程
|
||||||
|
{
|
||||||
|
close(log_pipe[1]); // 关闭写端
|
||||||
|
char log_buffer[BUFFER_SIZE];
|
||||||
|
while (read(log_pipe[0], log_buffer, BUFFER_SIZE) > 0)
|
||||||
|
{
|
||||||
|
printf("日志: %s\n", log_buffer);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("服务器已启动,等待客户端连接...\n");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||||
|
printf("客户端进入,当前资源被占用\n");
|
||||||
|
|
||||||
|
int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
|
||||||
|
if (client_socket == -1)
|
||||||
|
{
|
||||||
|
perror("接受客户端连接失败");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("客户端连接成功,地址: %s\n", inet_ntoa(client_addr.sin_addr));
|
||||||
|
|
||||||
|
int *client_sock = malloc(sizeof(int));
|
||||||
|
*client_sock = client_socket;
|
||||||
|
|
||||||
|
pthread_t thread_id;
|
||||||
|
pthread_create(&thread_id, NULL, client_handler, client_sock);
|
||||||
|
pthread_detach(thread_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(server_socket);
|
||||||
|
// 释放信号量
|
||||||
|
dispatch_release(semaphore);
|
||||||
|
return 0;
|
||||||
|
}
|
5
sm2_key.pem
Normal file
5
sm2_key.pem
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGIAgEAMBQGCCqBHM9VAYItBggqgRzPVQGCLQRtMGsCAQEEIKX7OhW9A5qAXmDV
|
||||||
|
7A9V0QRtNRm/2gJKzR4yr8tBtZ3yoUQDQgAE9leBaJzrxR7z1gN9c4txWMjZwuOE
|
||||||
|
5n+4PoNOUDwQ9uZywkn2oaOV2oqUH/pgXZYMpWbyGSTlCtbYeunwZeT+8w==
|
||||||
|
-----END PRIVATE KEY-----
|
4
sm2_pub.pem
Normal file
4
sm2_pub.pem
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MFowFAYIKoEcz1UBgi0GCCqBHM9VAYItA0IABPZXgWic68Ue89YDfXOLcVjI2cLj
|
||||||
|
hOZ/uD6DTlA8EPbmcsJJ9qGjldqKlB/6YF2WDKVm8hkk5QrW2Hrp8GXk/vM=
|
||||||
|
-----END PUBLIC KEY-----
|
56
socketTestClient.c
Normal file
56
socketTestClient.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define PORT 8001
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int client_socket;
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
// 创建客户端 socket
|
||||||
|
client_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (client_socket == -1) {
|
||||||
|
perror("客户端 socket 创建失败");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置服务器地址
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
|
||||||
|
// 连接到服务器
|
||||||
|
if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||||||
|
perror("连接服务器失败");
|
||||||
|
close(client_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("连接服务器成功!\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
printf("输入要发送的消息: ");
|
||||||
|
fgets(buffer, BUFFER_SIZE, stdin);
|
||||||
|
buffer[strcspn(buffer, "\n")] = 0; // 去掉换行符
|
||||||
|
|
||||||
|
send(client_socket, buffer, strlen(buffer), 0);
|
||||||
|
|
||||||
|
if (strcmp(buffer, "exit") == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytes_read = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
|
||||||
|
if (bytes_read > 0) {
|
||||||
|
buffer[bytes_read] = '\0';
|
||||||
|
printf("服务器回复: %s\n", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(client_socket);
|
||||||
|
return 0;
|
||||||
|
}
|
99
socketTestServer.c
Normal file
99
socketTestServer.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define PORT 8001
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
#define MAX_CLIENTS 10
|
||||||
|
|
||||||
|
// 处理函数示例
|
||||||
|
void handle_function() {
|
||||||
|
printf("处理函数被调用!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客户端处理线程
|
||||||
|
void *client_handler(void *arg) {
|
||||||
|
int client_socket = *(int *)arg;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
|
||||||
|
while ((bytes_read = recv(client_socket, buffer, sizeof(buffer), 0)) > 0) {
|
||||||
|
buffer[bytes_read] = '\0';
|
||||||
|
printf("接收到客户端消息: %s\n", buffer);
|
||||||
|
|
||||||
|
// 判断是否执行处理函数
|
||||||
|
if (strcmp(buffer, "execute") == 0) {
|
||||||
|
handle_function();
|
||||||
|
send(client_socket, "处理函数已执行\n", strlen("处理函数已执行\n"), 0);
|
||||||
|
} else {
|
||||||
|
send(client_socket, "收到消息\n", strlen("收到消息\n"), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(client_socket);
|
||||||
|
printf("客户端断开连接\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int server_socket, client_socket;
|
||||||
|
struct sockaddr_in server_addr, client_addr;
|
||||||
|
socklen_t client_addr_len = sizeof(client_addr);
|
||||||
|
pthread_t thread_pool[MAX_CLIENTS];
|
||||||
|
int client_count = 0;
|
||||||
|
|
||||||
|
// 创建服务器 socket
|
||||||
|
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server_socket == -1) {
|
||||||
|
perror("服务器 socket 创建失败");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置服务器地址
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
// 绑定服务器 socket
|
||||||
|
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||||||
|
perror("绑定失败");
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始监听
|
||||||
|
if (listen(server_socket, MAX_CLIENTS) == -1) {
|
||||||
|
perror("监听失败");
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("服务器已启动,等待客户端连接...\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// 接受客户端连接
|
||||||
|
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
|
||||||
|
if (client_socket == -1) {
|
||||||
|
perror("接受客户端连接失败");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("客户端连接成功,地址: %s\n", inet_ntoa(client_addr.sin_addr));
|
||||||
|
|
||||||
|
// 创建线程处理客户端
|
||||||
|
if (pthread_create(&thread_pool[client_count++], NULL, client_handler, &client_socket) != 0) {
|
||||||
|
perror("线程创建失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防止线程池溢出
|
||||||
|
if (client_count >= MAX_CLIENTS) {
|
||||||
|
client_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(server_socket);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user