linux/client.c

175 lines
4.6 KiB
C
Raw Normal View History

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>
#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;
}