feat:功能完成
This commit is contained in:
parent
1cee5d570f
commit
1de826649b
3
.gitignore
vendored
3
.gitignore
vendored
@ -51,4 +51,5 @@
|
|||||||
*.plist
|
*.plist
|
||||||
|
|
||||||
./files/*
|
./files/*
|
||||||
./newfile/*
|
./newfile/*
|
||||||
|
./test/*
|
1791
GmSSL 3.1.1 Linux.sh
1791
GmSSL 3.1.1 Linux.sh
File diff suppressed because it is too large
Load Diff
77
client.c
77
client.c
@ -13,10 +13,9 @@
|
|||||||
|
|
||||||
void upload_file(int client_socket)
|
void upload_file(int client_socket)
|
||||||
{
|
{
|
||||||
//发送通知服务器是上传文件
|
// 发送通知服务器是上传文件
|
||||||
send(client_socket, "upload", strlen("upload"), 0);
|
send(client_socket, "upload", strlen("upload"), 0);
|
||||||
|
|
||||||
|
|
||||||
char file_name[BUFFER_SIZE];
|
char file_name[BUFFER_SIZE];
|
||||||
char file_content[BUFFER_SIZE];
|
char file_content[BUFFER_SIZE];
|
||||||
mkdir("./newfile", 0777);
|
mkdir("./newfile", 0777);
|
||||||
@ -39,15 +38,10 @@ void upload_file(int client_socket)
|
|||||||
}
|
}
|
||||||
printf("文件名部分是: %s\n", base_name);
|
printf("文件名部分是: %s\n", base_name);
|
||||||
|
|
||||||
// 用户输入文件内容
|
|
||||||
printf("输入文件内容(输入完毕后按回车结束):\n");
|
|
||||||
getchar(); // 清除上一次输入的换行符
|
|
||||||
fgets(file_content, BUFFER_SIZE, stdin);
|
|
||||||
|
|
||||||
char dir_name[256];
|
char dir_name[256];
|
||||||
snprintf(dir_name, 256, "./newfile/%s", file_name);
|
snprintf(dir_name, 256, "./newfile/%s", file_name);
|
||||||
printf("文件路径是: %s\n", dir_name);
|
printf("文件路径是: %s\n", dir_name);
|
||||||
|
|
||||||
// 根据dir_name目录,file_name为文件名创建文件并将输入内容写入文件
|
// 根据dir_name目录,file_name为文件名创建文件并将输入内容写入文件
|
||||||
FILE *plain_file = fopen(dir_name, "w");
|
FILE *plain_file = fopen(dir_name, "w");
|
||||||
if (!plain_file)
|
if (!plain_file)
|
||||||
@ -55,10 +49,22 @@ void upload_file(int client_socket)
|
|||||||
perror("文件创建失败");
|
perror("文件创建失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 用户输入文件内容
|
||||||
|
printf("请输入文件内容,输入 EOF 表示结束:\n");
|
||||||
|
getchar(); // 清除上一次输入的换行符
|
||||||
|
while (fgets(file_content, sizeof(file_content), stdin))
|
||||||
|
{
|
||||||
|
if (strcmp(file_content, "EOF\n") == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fputs(file_content, plain_file);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(plain_file, "%s", file_content);
|
fprintf(plain_file, "%s", file_content);
|
||||||
fclose(plain_file);
|
fclose(plain_file);
|
||||||
printf("文件创建成功,准备上传。\n");
|
printf("文件创建成功,准备上传。\n");
|
||||||
|
|
||||||
// 发送文件名(不含后缀)到服务器
|
// 发送文件名(不含后缀)到服务器
|
||||||
send(client_socket, base_name, strlen(base_name), 0);
|
send(client_socket, base_name, strlen(base_name), 0);
|
||||||
// 等待服务器确认收到文件名
|
// 等待服务器确认收到文件名
|
||||||
@ -73,23 +79,35 @@ void upload_file(int client_socket)
|
|||||||
printf("服务端未确认文件名。\n");
|
printf("服务端未确认文件名。\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送文件内容到服务器
|
// 发送文件内容到服务器
|
||||||
FILE *file = fopen(file_name, "rb");
|
FILE *file = fopen(dir_name, "r");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
perror("文件打开失败");
|
perror("文件打开失败");
|
||||||
|
close(client_socket);
|
||||||
return;
|
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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 发送文件内容
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
int bytes_read;
|
while (!feof(file))
|
||||||
// 分块读取文件内容并发送到服务端
|
|
||||||
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0)
|
|
||||||
{
|
{
|
||||||
if (send(client_socket, buffer, bytes_read, 0) < 0)
|
int bytes_read = fread(buffer, 1, BUFFER_SIZE, file);
|
||||||
|
if (bytes_read > 0)
|
||||||
{
|
{
|
||||||
perror("发送文件数据失败");
|
send(client_socket, buffer, bytes_read, 0);
|
||||||
fclose(file);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -99,24 +117,27 @@ void upload_file(int client_socket)
|
|||||||
// 等待服务器发送加密压缩包的路径
|
// 等待服务器发送加密压缩包的路径
|
||||||
char compressed_path[BUFFER_SIZE] = {0};
|
char compressed_path[BUFFER_SIZE] = {0};
|
||||||
ssize_t bytes_received = read(client_socket, compressed_path, BUFFER_SIZE - 1);
|
ssize_t bytes_received = read(client_socket, compressed_path, BUFFER_SIZE - 1);
|
||||||
if (bytes_received > 0) {
|
if (bytes_received > 0)
|
||||||
compressed_path[bytes_received] = '\0'; // 确保字符串以空字符结尾
|
{
|
||||||
|
compressed_path[bytes_received] = '\0'; // 确保字符串以空字符结尾
|
||||||
printf("服务器发送的加密压缩包路径是: %s\n", compressed_path);
|
printf("服务器发送的加密压缩包路径是: %s\n", compressed_path);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
perror("读取服务器发送的路径失败");
|
perror("读取服务器发送的路径失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void download_file(int client_socket)
|
void download_file(int client_socket)
|
||||||
{
|
{
|
||||||
|
// 发送通知服务器是下载文件
|
||||||
|
send(client_socket, "download", strlen("download"), 0);
|
||||||
char output_file_name[BUFFER_SIZE];
|
char output_file_name[BUFFER_SIZE];
|
||||||
char file_path[BUFFER_SIZE];
|
char file_path[BUFFER_SIZE];
|
||||||
|
|
||||||
printf("输入要下载的文件(加密后的文件压缩包)完整路径: ");
|
printf("输入要下载的文件(加密后的文件压缩包)完整路径: ");
|
||||||
scanf("%s", file_path);
|
scanf("%s", file_path);
|
||||||
|
|
||||||
// 发送下载请求到服务器
|
|
||||||
send(client_socket, "download", strlen("download"), 0);
|
|
||||||
send(client_socket, file_path, strlen(file_path), 0);
|
send(client_socket, file_path, strlen(file_path), 0);
|
||||||
// 等待服务端准备完成的信号
|
// 等待服务端准备完成的信号
|
||||||
char ack[BUFFER_SIZE] = {0};
|
char ack[BUFFER_SIZE] = {0};
|
||||||
@ -132,7 +153,7 @@ void download_file(int client_socket)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 创建输出文件
|
// 创建输出文件
|
||||||
|
|
||||||
FILE *output = fopen("./output.txt", "wb");
|
FILE *output = fopen("./output.txt", "wb");
|
||||||
if (!output)
|
if (!output)
|
||||||
{
|
{
|
||||||
@ -144,6 +165,14 @@ void download_file(int client_socket)
|
|||||||
int bytes_read;
|
int bytes_read;
|
||||||
while ((bytes_read = read(client_socket, buffer, BUFFER_SIZE)) > 0)
|
while ((bytes_read = read(client_socket, buffer, BUFFER_SIZE)) > 0)
|
||||||
{
|
{
|
||||||
|
// 检查是否包含结束标志
|
||||||
|
if (strstr(buffer, "stop") != NULL)
|
||||||
|
{
|
||||||
|
fwrite(buffer, 1, bytes_read - strlen("stop"), output); // 写入实际数据
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fwrite(buffer, 1, bytes_read, output);
|
||||||
|
printf("接收到 %d 字节数据。\n", bytes_read);
|
||||||
fwrite(buffer, 1, bytes_read, output);
|
fwrite(buffer, 1, bytes_read, output);
|
||||||
}
|
}
|
||||||
fclose(output);
|
fclose(output);
|
||||||
|
1
files/20241218160257/abc.enc
Normal file
1
files/20241218160257/abc.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
ùê‰ç‡¥on#˜ZhiT¯
|
BIN
files/20241218160257/abc.gz
Normal file
BIN
files/20241218160257/abc.gz
Normal file
Binary file not shown.
@ -1 +1,2 @@
|
|||||||
123
|
123
|
||||||
|
EOF
|
1
files/20241218161242/test.enc
Normal file
1
files/20241218161242/test.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
!e‹;`žSCÿCŠ·î¦
|
BIN
files/20241218161242/test.gz
Normal file
BIN
files/20241218161242/test.gz
Normal file
Binary file not shown.
2
files/20241218161242/test.txt
Normal file
2
files/20241218161242/test.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
jkflsdj
|
||||||
|
EOF
|
1
files/20241218171517/123.enc
Normal file
1
files/20241218171517/123.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
я€¦ґGЫ©^µ±И† †
|
BIN
files/20241218171517/123.gz
Normal file
BIN
files/20241218171517/123.gz
Normal file
Binary file not shown.
2
files/20241218171517/123.txt
Normal file
2
files/20241218171517/123.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fdjksalfj
|
||||||
|
EOF
|
1
files/20241218171921/345.enc
Normal file
1
files/20241218171921/345.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
:’(°W¸@BăĂý‹
|
BIN
files/20241218171921/345.gz
Normal file
BIN
files/20241218171921/345.gz
Normal file
Binary file not shown.
2
files/20241218171921/345.txt
Normal file
2
files/20241218171921/345.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOF
|
1
files/decrypt/123.enc
Normal file
1
files/decrypt/123.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
я€¦ґGЫ©^µ±И† †
|
2
files/decrypt/123.txt
Normal file
2
files/decrypt/123.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fdjksalfj
|
||||||
|
EOF
|
1
files/decrypt/345.enc
Normal file
1
files/decrypt/345.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
:’(°W¸@BăĂý‹
|
2
files/decrypt/345.txt
Normal file
2
files/decrypt/345.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOF
|
1
files/decrypt/test.enc
Normal file
1
files/decrypt/test.enc
Normal file
@ -0,0 +1 @@
|
|||||||
|
!e‹;`žSCÿCŠ·î¦
|
@ -1 +1,2 @@
|
|||||||
123
|
fdjksalfj
|
||||||
|
EOF
|
||||||
|
@ -1 +0,0 @@
|
|||||||
1233
|
|
@ -1 +0,0 @@
|
|||||||
1234
|
|
2
newfile/345.txt
Normal file
2
newfile/345.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOF
|
2
newfile/abc.txt
Normal file
2
newfile/abc.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOF
|
2
newfile/test.txt
Normal file
2
newfile/test.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
jkflsdj
|
||||||
|
EOF
|
2
output.txt
Normal file
2
output.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
123
|
||||||
|
EOF
|
285
server.c
285
server.c
@ -166,7 +166,7 @@ int sm4_cbc_padding_decrypt_file(const char *input_file, const char *output_file
|
|||||||
// 最后一块,带填充解密
|
// 最后一块,带填充解密
|
||||||
if (sm4_cbc_padding_decrypt(&dec_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
if (sm4_cbc_padding_decrypt(&dec_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "解密失败。\n");
|
fprintf(stderr, "带填充解密解密失败。\n");
|
||||||
fclose(in_file);
|
fclose(in_file);
|
||||||
fclose(out_file);
|
fclose(out_file);
|
||||||
return 0;
|
return 0;
|
||||||
@ -177,7 +177,7 @@ int sm4_cbc_padding_decrypt_file(const char *input_file, const char *output_file
|
|||||||
// 中间块,不需要处理填充
|
// 中间块,不需要处理填充
|
||||||
if (sm4_cbc_padding_decrypt(&dec_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
if (sm4_cbc_padding_decrypt(&dec_key, iv, input_block, bytes_read, output_block, &outlen) != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "解密失败。\n");
|
fprintf(stderr, "不需要处理填充解密失败。\n");
|
||||||
fclose(in_file);
|
fclose(in_file);
|
||||||
fclose(out_file);
|
fclose(out_file);
|
||||||
return 0;
|
return 0;
|
||||||
@ -191,6 +191,40 @@ int sm4_cbc_padding_decrypt_file(const char *input_file, const char *output_file
|
|||||||
return 1; // 成功
|
return 1; // 成功
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void extract_path_and_filename(const char *input, char *path, char *filename) {
|
||||||
|
int last_slash_index = -1; // 记录最后一个 '/' 的位置
|
||||||
|
int last_dot_index = -1; // 记录最后一个 '.' 的位置
|
||||||
|
|
||||||
|
// 遍历路径字符串,找到最后一个 '/' 和 '.'
|
||||||
|
for (int i = 0; input[i] != '\0'; i++) {
|
||||||
|
if (input[i] == '/') {
|
||||||
|
last_slash_index = i; // 更新最后一个 '/' 的位置
|
||||||
|
}
|
||||||
|
if (input[i] == '.') {
|
||||||
|
last_dot_index = i; // 更新最后一个 '.' 的位置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取路径部分(从开头到最后一个 '/')
|
||||||
|
if (last_slash_index != -1) {
|
||||||
|
strncpy(path, input, last_slash_index + 1);
|
||||||
|
path[last_slash_index + 1] = '\0'; // 确保路径部分以 '\0' 结尾
|
||||||
|
} else {
|
||||||
|
path[0] = '\0'; // 如果没有 '/', 为空
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果 '.' 在 '/' 之前或没有 '.', 忽略后缀处理
|
||||||
|
if (last_dot_index <= last_slash_index) {
|
||||||
|
last_dot_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取文件名部分(从最后一个 '/' 到最后一个 '.' 之间)
|
||||||
|
int j = 0; // 文件名的索引
|
||||||
|
for (int i = last_slash_index + 1; i < (last_dot_index == -1 ? strlen(input) : last_dot_index); i++) {
|
||||||
|
filename[j++] = input[i];
|
||||||
|
}
|
||||||
|
filename[j] = '\0'; // 添加字符串结束符
|
||||||
|
}
|
||||||
// 客户端处理线程
|
// 客户端处理线程
|
||||||
void *client_handler(void *arg)
|
void *client_handler(void *arg)
|
||||||
{
|
{
|
||||||
@ -198,148 +232,161 @@ void *client_handler(void *arg)
|
|||||||
free(arg);
|
free(arg);
|
||||||
|
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
// 初始化缓冲区为 0
|
|
||||||
memset(buffer, 0, BUFFER_SIZE);
|
|
||||||
|
|
||||||
// 接收第一个参数判断参数客户端需要上传还是下载
|
while (1)
|
||||||
int bytes = read(client_socket, buffer, BUFFER_SIZE - 1);// 预留一个字节用于NULL终止符
|
|
||||||
if (bytes <= 0)
|
|
||||||
{
|
{
|
||||||
perror("接收客户端命令失败");
|
printf("等待客户端发送命令中...\n");
|
||||||
return NULL;
|
// 初始化缓冲区为 0
|
||||||
}
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
buffer[bytes] = '\0'; // 确保以 NULL 结尾
|
// 接收第一个参数判断参数客户端需要上传还是下载
|
||||||
char upload_or_download[256] ;
|
int bytes = read(client_socket, buffer, BUFFER_SIZE - 1); // 预留一个字节用于NULL终止符
|
||||||
snprintf(upload_or_download, sizeof(upload_or_download), "%s", buffer);
|
|
||||||
printf("客户端发起请求:%s,等待后续指令....\n", upload_or_download);
|
|
||||||
|
|
||||||
char origin_file_path[256], dir_name[128], file_path[256], compressed_file[256], decrypted_file[256];
|
|
||||||
|
|
||||||
if (strcmp(upload_or_download, "upload") == 0)
|
|
||||||
{
|
|
||||||
// 接收文件名(不含后缀)
|
|
||||||
int bytes = read(client_socket, buffer, BUFFER_SIZE);
|
|
||||||
if (bytes <= 0)
|
if (bytes <= 0)
|
||||||
{
|
{
|
||||||
perror("接收文件名失败");
|
perror("接收客户端命令失败");
|
||||||
return NULL;
|
break; // 如果读取失败或连接关闭,退出循环
|
||||||
}
|
}
|
||||||
buffer[bytes] = '\0'; // 确保以 NULL 结尾
|
buffer[bytes] = '\0'; // 确保以 NULL 结尾
|
||||||
char file_name[256];
|
char upload_or_download[256];
|
||||||
snprintf(file_name, sizeof(file_name), "%s", buffer);
|
snprintf(upload_or_download, sizeof(upload_or_download), "%s", buffer);
|
||||||
printf("接收文件名:%s\n", file_name);
|
printf("客户端发起请求:%s, 等待后续指令....\n", upload_or_download);
|
||||||
// 发送 ACK 确认
|
|
||||||
send(client_socket, "ACK", strlen("ACK"), 0);
|
|
||||||
|
|
||||||
// 先生成./files目录,再生成时间戳目录,调用 create_timestamp_dir 函数,生成一个基于时间戳的目录名称,并将其存储在 dir_name 中
|
char origin_file_path[256], dir_name[128], file_path[256], compressed_file[256], decrypted_file[256];
|
||||||
create_timestamp_dir(dir_name);
|
|
||||||
|
|
||||||
// 根据传入的文件名以及时间戳拼接生成源文件路径
|
if (strcmp(upload_or_download, "upload") == 0)
|
||||||
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);
|
|
||||||
// 解密的文件路径
|
|
||||||
snprintf(decrypted_file, sizeof(decrypted_file), "./files/decrypt/%s_decrypted.txt", 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;
|
int bytes = read(client_socket, buffer, BUFFER_SIZE);
|
||||||
}
|
if (bytes <= 0)
|
||||||
// 按块读取源文件内容并保存到origin_file_path
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int bytes = read(client_socket, buffer, BUFFER_SIZE -1);
|
|
||||||
if (bytes < 0)
|
|
||||||
{
|
{
|
||||||
perror("读取数据失败");
|
perror("接收文件名失败");
|
||||||
fclose(file);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// 检测是否接收到结束标志
|
buffer[bytes] = '\0'; // 确保以 NULL 结尾
|
||||||
if (strncmp(buffer, "EOF", 3) == 0)
|
char file_name[256];
|
||||||
break;
|
snprintf(file_name, sizeof(file_name), "%s", buffer);
|
||||||
// 将数据写入文件
|
printf("接收文件名:%s\n", file_name);
|
||||||
if (fwrite(buffer, 1, bytes, file) != bytes)
|
// 发送 ACK 确认
|
||||||
|
send(client_socket, "ACK", strlen("ACK"), 0);
|
||||||
|
|
||||||
|
// 先生成./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);
|
||||||
|
// 解密的文件路径
|
||||||
|
snprintf(decrypted_file, sizeof(decrypted_file), "./files/decrypt/%s_decrypted.txt", 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, "w");
|
||||||
|
if (!file)
|
||||||
{
|
{
|
||||||
perror("写入文件失败");
|
perror("文件打开失败");
|
||||||
fclose(file);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
// 接收分块数据
|
||||||
|
int bytes_received;
|
||||||
|
while ((bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0)) > 0)
|
||||||
|
{
|
||||||
|
// 检查是否包含结束标志
|
||||||
|
if (strstr(buffer, "EOF") != NULL)
|
||||||
|
{
|
||||||
|
fwrite(buffer, 1, bytes_received - strlen("EOF"), file); // 写入实际数据
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fwrite(buffer, 1, bytes_received, file);
|
||||||
|
printf("接收到 %d 字节数据。\n", bytes_received);
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
log_operation("文件已接收。\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);
|
||||||
|
|
||||||
|
// 发送压缩的加密文件路径给客户端
|
||||||
|
send(client_socket, compressed_file, strlen(compressed_file), 0);
|
||||||
|
log_operation(log_message_compressed_file);
|
||||||
}
|
}
|
||||||
fclose(file);
|
else if (strcmp(upload_or_download, "download") == 0)
|
||||||
|
|
||||||
log_operation("文件已接收。\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);
|
|
||||||
|
|
||||||
// 发送压缩的加密文件路径给客户端
|
|
||||||
send(client_socket, compressed_file, strlen(compressed_file), 0);
|
|
||||||
log_operation(log_message_compressed_file);
|
|
||||||
}
|
|
||||||
else if (strcmp(upload_or_download, "download") == 0)
|
|
||||||
{
|
|
||||||
printf("接收到下载请求...\n");
|
|
||||||
|
|
||||||
memset(buffer, 0, BUFFER_SIZE);
|
|
||||||
// 读取文件路径
|
|
||||||
read(client_socket, buffer, BUFFER_SIZE);
|
|
||||||
|
|
||||||
sprintf(compressed_file, "%s", buffer);
|
|
||||||
|
|
||||||
// 解压缩、解密并发送给客户端
|
|
||||||
decompress_file(compressed_file, compressed_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);
|
printf("接收到下载请求...\n");
|
||||||
send(client_socket, buffer, bytes_read, 0);
|
|
||||||
}
|
|
||||||
fclose(file_to_send);
|
|
||||||
|
|
||||||
printf("文件发送完成。\n");
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
// 删除解密后的文件
|
// 读取文件路径
|
||||||
// remove(decrypted_file);
|
read(client_socket, buffer, BUFFER_SIZE);
|
||||||
}
|
|
||||||
else
|
char path[256]; // 存储提取的路径(无后缀)
|
||||||
{
|
char filename[256]; // 存储提取的文件名
|
||||||
perror("读取客户端命令失败");
|
extract_path_and_filename(buffer, path, filename);
|
||||||
|
//压缩包路径
|
||||||
|
sprintf(compressed_file, "%s", buffer);
|
||||||
|
// 解压后的加密文件路径
|
||||||
|
sprintf(file_path, "./files/decrypt/%s.enc",filename);
|
||||||
|
// 解密文件路径
|
||||||
|
sprintf(decrypted_file, "./files/decrypt/%s.txt", filename);
|
||||||
|
printf("%s\n", compressed_file);
|
||||||
|
printf("%s\n", file_path);
|
||||||
|
printf("%s\n", decrypted_file);
|
||||||
|
// 解压缩、解密并发送给客户端
|
||||||
|
decompress_file(compressed_file, file_path);
|
||||||
|
printf("文件解压缩完成。\n");
|
||||||
|
|
||||||
|
printf("正在解密文件...\n");
|
||||||
|
sm4_cbc_padding_decrypt_file(file_path, 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");
|
||||||
|
// 向客户端发送 "READY" 信号
|
||||||
|
send(client_socket, "stop", strlen("stop"), 0);
|
||||||
|
// 删除解密后的文件
|
||||||
|
// remove(decrypted_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
perror("读取客户端命令失败");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0, BUFFER_SIZE); // 清空缓冲区,准备接收下一个命令
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭连接
|
// 关闭连接
|
||||||
close(client_socket);
|
close(client_socket);
|
||||||
dispatch_semaphore_signal(semaphore);
|
dispatch_semaphore_signal(semaphore);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
BIN
test/client
Executable file
BIN
test/client
Executable file
Binary file not shown.
80
test/client.c
Normal file
80
test/client.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define PORT 8002
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int client_socket;
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
char filename[100];
|
||||||
|
|
||||||
|
// 创建客户端 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");
|
||||||
|
|
||||||
|
// 输入文件名并创建文件
|
||||||
|
printf("请输入要创建的文件名(例如 output.txt):");
|
||||||
|
fgets(filename, sizeof(filename), stdin);
|
||||||
|
filename[strcspn(filename, "\n")] = 0; // 去掉换行符
|
||||||
|
|
||||||
|
FILE *file = fopen(filename, "w");
|
||||||
|
if (!file) {
|
||||||
|
perror("文件创建失败");
|
||||||
|
close(client_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("请输入文件内容,输入 EOF 表示结束:\n");
|
||||||
|
while (fgets(buffer, sizeof(buffer), stdin)) {
|
||||||
|
if (strcmp(buffer, "EOF\n") == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fputs(buffer, file);
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// 重新打开文件以读取并发送给服务器
|
||||||
|
file = fopen(filename, "r");
|
||||||
|
if (!file) {
|
||||||
|
perror("文件打开失败");
|
||||||
|
close(client_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分块发送文件内容
|
||||||
|
int bytes_read;
|
||||||
|
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0) {
|
||||||
|
send(client_socket, buffer, bytes_read, 0);
|
||||||
|
printf("发送 %d 字节数据。\n", bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("文件内容已发送到服务器。\n");
|
||||||
|
|
||||||
|
// 关闭文件和 socket
|
||||||
|
fclose(file);
|
||||||
|
close(client_socket);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
test/received_file.txt
Normal file
1
test/received_file.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
jfkdlsajfkalEOF
|
BIN
test/server
Executable file
BIN
test/server
Executable file
Binary file not shown.
85
test/server.c
Normal file
85
test/server.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define PORT 8002
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int server_socket, client_socket;
|
||||||
|
struct sockaddr_in server_addr, client_addr;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 SO_REUSEADDR
|
||||||
|
int opt = 1;
|
||||||
|
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
|
||||||
|
perror("设置 SO_REUSEADDR 失败");
|
||||||
|
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, 5) == -1) {
|
||||||
|
perror("监听失败");
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("服务器已启动,等待客户端连接...\n");
|
||||||
|
|
||||||
|
// 接受客户端连接
|
||||||
|
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
|
||||||
|
if (client_socket == -1) {
|
||||||
|
perror("接受客户端连接失败");
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("客户端连接成功。\n");
|
||||||
|
|
||||||
|
// 打开文件以写入接收到的数据
|
||||||
|
FILE *file = fopen("received_file.txt", "w");
|
||||||
|
if (!file) {
|
||||||
|
perror("文件打开失败");
|
||||||
|
close(client_socket);
|
||||||
|
close(server_socket);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接收分块数据
|
||||||
|
int bytes_received;
|
||||||
|
while ((bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0)) > 0) {
|
||||||
|
fwrite(buffer, 1, bytes_received, file);
|
||||||
|
printf("接收到 %d 字节数据。\n", bytes_received);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("文件接收完成,已保存为 received_file.txt\n");
|
||||||
|
|
||||||
|
// 关闭文件和 socket
|
||||||
|
fclose(file);
|
||||||
|
close(client_socket);
|
||||||
|
close(server_socket);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
test/test.txt
Normal file
1
test/test.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
jfkdlsajfkalEOF
|
Loading…
Reference in New Issue
Block a user