linux/client.c
2024-12-18 17:24:29 +08:00

239 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#define PORT 8001
#define BUFFER_SIZE 1024
void upload_file(int client_socket)
{
// 发送通知服务器是上传文件
send(client_socket, "upload", strlen("upload"), 0);
char file_name[BUFFER_SIZE];
char file_content[BUFFER_SIZE];
mkdir("./newfile", 0777);
// 用户输入文件名
printf("输入要创建的文件名(不带路径,需携带后缀例如abc.txt: ");
scanf("%s", file_name);
// 提取文件名部分(去掉后缀)
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);
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");
if (!plain_file)
{
perror("文件创建失败");
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);
fclose(plain_file);
printf("文件创建成功,准备上传。\n");
// 发送文件名(不含后缀)到服务器
send(client_socket, base_name, strlen(base_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(dir_name, "r");
if (!file)
{
perror("文件打开失败");
close(client_socket);
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];
while (!feof(file))
{
int bytes_read = fread(buffer, 1, BUFFER_SIZE, file);
if (bytes_read > 0)
{
send(client_socket, buffer, bytes_read, 0);
}
}
fclose(file);
// 发送文件传输结束标志
send(client_socket, "EOF", strlen("EOF"), 0);
printf("文件已上传。\n");
// 等待服务器发送加密压缩包的路径
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("读取服务器发送的路径失败");
}
}
void download_file(int client_socket)
{
// 发送通知服务器是下载文件
send(client_socket, "download", strlen("download"), 0);
char output_file_name[BUFFER_SIZE];
char file_path[BUFFER_SIZE];
printf("输入要下载的文件(加密后的文件压缩包)完整路径: ");
scanf("%s", file_path);
send(client_socket, file_path, strlen(file_path), 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;
}
// 创建输出文件
FILE *output = fopen("./output.txt", "wb");
if (!output)
{
perror("文件打开失败");
return;
}
// 接收文件数据
char buffer[BUFFER_SIZE];
int bytes_read;
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);
}
fclose(output);
printf("文件已下载保存在当前目录下的output.txt中。\n");
}
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;
}