2024-12-17 10:49:27 +08:00
|
|
|
|
// client.c
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <unistd.h>
|
2024-12-18 00:21:22 +08:00
|
|
|
|
#include <sys/stat.h>
|
2024-12-17 10:49:27 +08:00
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
|
|
#define PORT 8001
|
|
|
|
|
#define BUFFER_SIZE 1024
|
|
|
|
|
|
|
|
|
|
void upload_file(int client_socket)
|
|
|
|
|
{
|
2024-12-18 13:05:31 +08:00
|
|
|
|
//发送通知服务器是上传文件
|
|
|
|
|
send(client_socket, "upload", strlen("upload"), 0);
|
|
|
|
|
|
|
|
|
|
|
2024-12-17 10:49:27 +08:00
|
|
|
|
char file_name[BUFFER_SIZE];
|
|
|
|
|
char file_content[BUFFER_SIZE];
|
2024-12-18 00:21:22 +08:00
|
|
|
|
mkdir("./newfile", 0777);
|
2024-12-17 10:49:27 +08:00
|
|
|
|
// 用户输入文件名
|
2024-12-18 00:21:22 +08:00
|
|
|
|
printf("输入要创建的文件名(不带路径,需携带后缀)例如:abc.txt: ");
|
2024-12-17 10:49:27 +08:00
|
|
|
|
scanf("%s", file_name);
|
|
|
|
|
|
2024-12-18 00:21:22 +08:00
|
|
|
|
// 提取文件名部分(去掉后缀)
|
|
|
|
|
char base_name[BUFFER_SIZE];
|
|
|
|
|
const char *dot = strrchr(file_name, '.');
|
|
|
|
|
if (dot && dot != file_name)
|
|
|
|
|
{
|
|
|
|
|
strncpy(base_name, file_name, dot - file_name);
|
|
|
|
|
base_name[dot - file_name] = '\0';
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 如果没有后缀,直接使用原文件名
|
|
|
|
|
strcpy(base_name, file_name);
|
|
|
|
|
}
|
|
|
|
|
printf("文件名部分是: %s\n", base_name);
|
|
|
|
|
|
2024-12-17 10:49:27 +08:00
|
|
|
|
// 用户输入文件内容
|
|
|
|
|
printf("输入文件内容(输入完毕后按回车结束):\n");
|
|
|
|
|
getchar(); // 清除上一次输入的换行符
|
|
|
|
|
fgets(file_content, BUFFER_SIZE, stdin);
|
|
|
|
|
|
2024-12-18 00:21:22 +08:00
|
|
|
|
char dir_name[256];
|
|
|
|
|
snprintf(dir_name, 256, "./newfile/%s", file_name);
|
|
|
|
|
printf("文件路径是: %s\n", dir_name);
|
|
|
|
|
|
|
|
|
|
// 根据dir_name目录,file_name为文件名创建文件并将输入内容写入文件
|
|
|
|
|
FILE *plain_file = fopen(dir_name, "w");
|
2024-12-17 10:49:27 +08:00
|
|
|
|
if (!plain_file)
|
|
|
|
|
{
|
|
|
|
|
perror("文件创建失败");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
fprintf(plain_file, "%s", file_content);
|
|
|
|
|
fclose(plain_file);
|
2024-12-18 13:05:31 +08:00
|
|
|
|
printf("文件创建成功,准备上传。\n");
|
|
|
|
|
|
2024-12-18 00:21:22 +08:00
|
|
|
|
// 发送文件名(不含后缀)到服务器
|
|
|
|
|
send(client_socket, base_name, strlen(base_name), 0);
|
2024-12-17 10:49:27 +08:00
|
|
|
|
// 等待服务器确认收到文件名
|
|
|
|
|
char ack[BUFFER_SIZE] = {0};
|
|
|
|
|
read(client_socket, ack, BUFFER_SIZE);
|
|
|
|
|
if (strcmp(ack, "ACK") == 0)
|
|
|
|
|
{
|
|
|
|
|
printf("服务端确认文件名。\n");
|
2024-12-18 00:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-12-17 10:49:27 +08:00
|
|
|
|
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");
|
2024-12-18 13:05:31 +08:00
|
|
|
|
// 等待服务器发送加密压缩包的路径
|
|
|
|
|
char compressed_path[BUFFER_SIZE] = {0};
|
|
|
|
|
ssize_t bytes_received = read(client_socket, compressed_path, BUFFER_SIZE - 1);
|
|
|
|
|
if (bytes_received > 0) {
|
|
|
|
|
compressed_path[bytes_received] = '\0'; // 确保字符串以空字符结尾
|
|
|
|
|
printf("服务器发送的加密压缩包路径是: %s\n", compressed_path);
|
|
|
|
|
} else {
|
|
|
|
|
perror("读取服务器发送的路径失败");
|
|
|
|
|
}
|
2024-12-17 10:49:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void download_file(int client_socket)
|
|
|
|
|
{
|
|
|
|
|
char output_file_name[BUFFER_SIZE];
|
2024-12-18 13:05:31 +08:00
|
|
|
|
char file_path[BUFFER_SIZE];
|
2024-12-17 10:49:27 +08:00
|
|
|
|
|
2024-12-18 13:05:31 +08:00
|
|
|
|
printf("输入要下载的文件(加密后的文件压缩包)完整路径: ");
|
|
|
|
|
scanf("%s", file_path);
|
|
|
|
|
|
2024-12-17 10:49:27 +08:00
|
|
|
|
// 发送下载请求到服务器
|
2024-12-18 13:05:31 +08:00
|
|
|
|
send(client_socket, "download", strlen("download"), 0);
|
|
|
|
|
send(client_socket, file_path, strlen(file_path), 0);
|
2024-12-17 10:49:27 +08:00
|
|
|
|
// 等待服务端准备完成的信号
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// 创建输出文件
|
2024-12-18 13:05:31 +08:00
|
|
|
|
|
|
|
|
|
FILE *output = fopen("./output.txt", "wb");
|
2024-12-17 10:49:27 +08:00
|
|
|
|
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);
|
2024-12-18 13:05:31 +08:00
|
|
|
|
printf("文件已下载,保存在当前目录下的output.txt中。\n");
|
2024-12-17 10:49:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2024-12-18 13:05:31 +08:00
|
|
|
|
printf("请输入命令 (upload/download/exit): ");
|
2024-12-17 10:49:27 +08:00
|
|
|
|
scanf("%s", command);
|
|
|
|
|
|
2024-12-18 13:05:31 +08:00
|
|
|
|
if (strcmp(command, "upload") == 0)
|
2024-12-17 10:49:27 +08:00
|
|
|
|
{
|
|
|
|
|
upload_file(client_socket);
|
|
|
|
|
}
|
2024-12-18 13:05:31 +08:00
|
|
|
|
else if (strcmp(command, "download") == 0)
|
2024-12-17 10:49:27 +08:00
|
|
|
|
{
|
|
|
|
|
download_file(client_socket);
|
|
|
|
|
}
|
2024-12-18 13:05:31 +08:00
|
|
|
|
else if (strcmp(command, "exit") == 0)
|
2024-12-17 10:49:27 +08:00
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("未知命令,请重试。\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
close(client_socket);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|