远程文件控制
1.构建套接字socket的链接,实现两台电脑间一对一的通信。
2.实现本地文件操作及路径检索等功能,A电脑可通过通信传输的命令可以对B电脑本地文件进行操作。
3.实现文件传输功能,能够实现不同类型文件的传输。
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
#define BUFFER_SIZE 1024 //缓冲区文件大小
#define MAX_PATH 260 // 定义文件路径的最大长度
//文件检索
void searchFile(const char *basePath, const char *targetFile, char *result) {
char path[MAX_PATH]; //搜索起始路径
WIN32_FIND_DATA findFileData;//声明 结构体来存储找到的文件信息
HANDLE hFind = INVALID_HANDLE_VALUE;
snprintf(path, sizeof(path), "%s\\*", basePath);//加入通配符 //构造出搜索路径
hFind = FindFirstFile(path, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
return;
//使用 do-while 循环遍历目录中的所有项目
//跳过 "." 和 ".." 目录
do {
if (strcmp(findFileData.cFileName, ".") != 0 && strcmp(findFileData.cFileName, "..") != 0) {
snprintf(path, sizeof(path), "%s\\%s", basePath, findFileData.cFileName);
if (_stricmp(findFileData.cFileName, targetFile) == 0) {
_fullpath(result, path, MAX_PATH);
FindClose(hFind);
return;
}
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
searchFile(path, targetFile, result);
if (result[0] != '\0') {
FindClose(hFind);
return;
}
}
}
} while (FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind);
}
//关闭套接字并清理Winsock环境
void cleanup(SOCKET socket) {
closesocket(socket);
WSACleanup();
}
//定义了一个send_message函数,用于发送消息。它接收套接字和要发送的消息作为参数,计算消息的长度,然后使用send函数发送它。
int send_message(SOCKET socket, const char *message) {
int len = strlen(message);
return send(socket, message, len, 0);
}
//定义了一个receive_message函数,用于接收消息。它接收套接字、用于存储接收到的数据的缓冲区和缓冲区的大小作为参数。
//首先调用recv函数接收数据,然后如果接收到的数据长度大于0,就在缓冲区的末尾添加一个空字符,以确保数据是一个正确的字符串。
int receive_message(SOCKET socket, char *buffer, int bufferSize) {
int ret = recv(socket, buffer, bufferSize - 1, 0);
if (ret > 0) {
buffer[ret] = '\0'; //确保字符串
}
return ret;
}
//main函数的开始部分。定义了一些变量,包括用于存储Winsock数据的wsaData,客户端套接字clientSocket,服务器地址serverAddr,
//用于存储发送和接收数据的缓冲区buffer,用户的选择和函数的返回值ret,用于存储文件路径的filePath,和用于文件操作的文件指针fp。
int main() {
WSADATA wsaData;
SOCKET clientSocket;
struct sockaddr_in serverAddr;
char buffer[BUFFER_SIZE];
int choice, ret;
char filePath[MAX_PATH];
FILE *fp;
//这部分代码初始化Winsock。首先使用WSAStartup函数,如果返回值不为0,说明初始化失败,打印错误信息并返回1。
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed: %d\n", WSAGetLastError());
return 1;
}
//这部分代码创建客户端套接字。首先使用socket函数,如果返回值为INVALID_SOCKET,
//说明套接字创建失败,打印错误信息,清理Winsock环境并返回1。
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == INVALID_SOCKET) {
printf("Socket creation failed: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//这部分代码设置服务器地址。使用 inet_addr函数 将IP地址从点分十进制字符串转换为网络字节序的整数。
//然后使用htons函数将端口号从主机字节序转换为网络字节序。
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // assume server runs on localhost
serverAddr.sin_port = htons(8000);
//这部分代码连接到服务器。使用connect函数,如果返回值为SOCKET_ERROR,说明连接失败,打印错误信息,清理套接字和Winsock环境并返回1。
if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
printf("Connect failed: %d\n", WSAGetLastError());
cleanup(clientSocket);
return 1;
}
while (1) {
printf("选择一个操作:\n");
printf("1. 本地文件操作\n");
printf("2. 客户端对服务端文件操作)\n");
printf("3. 下载文件(凯撒加密)\n");
printf("4. 聊天\n");
printf("5. 退出\n");
printf("输入你的选择: ");
scanf("%d", &choice);
getchar();
switch (choice) {
case 1:
{
boolean flag = true;
while(flag) {
char localFilePath[MAX_PATH];
char localBuffer[BUFFER_SIZE];
FILE* localFp;
int localChoice;
printf("************本地文件操作**************\n");
printf("***1. 设置文件路径***\n");
printf("***2. 文件内容读取***\n");
printf("***3. 文件内容写入***\n");
printf("***4. 文件内容追加***\n");
printf("***5. 文件检索功能***\n");
printf("***6. 退出***\n");
printf("请选择操作 (1-6): ");
scanf("%d", &localChoice);
getchar(); // 消耗掉输入缓冲区中的换行符
switch(localChoice) {
case 1:
printf("请输入本地文件路径: ");
fgets(localFilePath, MAX_PATH, stdin);
localFilePath[strcspn(localFilePath, "\n")] = '\0'; // 去除换行符
printf("文件路径已设置为: %s\n", localFilePath);
break;
case 2:
localFp = fopen(localFilePath, "r");
if (localFp == NULL) {
printf("无法打开文件: %s\n", localFilePath);
} else {
printf("文件内容:\n");
while (fgets(localBuffer, BUFFER_SIZE, localFp) != NULL) {
printf("%s", localBuffer);
}
fclose(localFp);
}
break;
case 3:
localFp = fopen(localFilePath, "w");
if (localFp == NULL) {
printf("无法打开文件: %s\n", localFilePath);
} else {
printf("请输入要写入的内容:\n");
fgets(localBuffer, BUFFER_SIZE, stdin);
fprintf(localFp, "%s", localBuffer);
fclose(localFp);
printf("内容已成功写入文件\n");
}
break;
case 4:
localFp = fopen(localFilePath, "a");
if (localFp == NULL) {
printf("无法打开文件: %s\n", localFilePath);
} else {
printf("请输入要追加的内容:\n");
fgets(localBuffer, BUFFER_SIZE, stdin);
fprintf(localFp, "%s", localBuffer);
fclose(localFp);
printf("内容已成功追加到文件\n");
}
break;
case 5: {
char targetFile[MAX_PATH];//目标文件
char result[MAX_PATH] = "";//结果文件
printf("请输入要搜索的文件名: ");
fgets(targetFile, sizeof(targetFile), stdin);
targetFile[strcspn(targetFile, "\n")] = '\0'; // 去除换行符
searchFile("E:\\", targetFile, result);
if (result[0] != '\0') {
printf("文件找到,绝对路径为: %s\n", result);
} else {
printf("在E盘中未找到文件: %s\n", targetFile);
}
}
break;
case 6:
flag = false;
break;
default:
printf("无效的选择\n");
break;
}
}
}
break;
case 2:
{
int Choice;
boolean flage = true;
while(flage) {
printf("#########客户端对服务端文件操作#########\n");
printf("###1. 输入文件路径\n");
printf("###2. 读取文件内容\n");
printf("###3. 修改文件内容\n");
printf("###4. 追加文件内容\n");
printf("###5. 退出\n");
printf("请选择操作 (1-5): ");
scanf("%d", &Choice);
getchar(); // 消耗掉输入缓冲区中的换行符
switch(Choice) {
case 1:
//这部分代码处理用户选择1的情况,即设置文件路径。首先向服务器发送“SET_PATH”,然后提示用户输入文件路径,
//使用fgets函数从标准输入读取文件路径,然后去除文件路径末尾的换行符,将文件路径发送到服务器,接收服务器的响应,然后打印响应。
// 设置文件路径
send_message(clientSocket, "SET_PATH");
printf("Enter file path: ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = '\0'; // 去除换行符
send_message(clientSocket, buffer);
receive_message(clientSocket, buffer, BUFFER_SIZE);
printf("%s\n", buffer);
break;
//这部分代码处理用户选择2的情况,即读取文件内容。首先向服务器发送"READ",
//然后接收服务器的响应,如果响应的长度大于0,打印文件的内容,否则打印读取文件失败的消息。
case 2:
// 读取文件内容
send_message(clientSocket, "READ");
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
printf("File content:\n%s\n", buffer);
} else {
printf("Failed to read file.\n");
}
break;
//这部分代码处理用户选择3的情况,即修改文件内容。
//首先向服务器发送“WRITE”,然后提示用户输入新的文件内容,使用fgets函数从标准输入输入读取新的文件内容,
//然后去除文件内容末尾的换行符,将新的文件内容发送到服务器,接收服务器的响应,然后打印响应
case 3:
// 写入文件内容
send_message(clientSocket, "WRITE");
printf("Enter new file content: ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = '\0'; // 去除换行符
send_message(clientSocket, buffer);
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
printf("%s\n", buffer);
}
break;
case 4:
// 追加文件内容
send_message(clientSocket, "APPEND");
printf("请输入要追加的内容: ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = '\0'; // 去除换行符
send_message(clientSocket, buffer);
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
printf("服务器响应: %s\n", buffer);
}
break;
case 5:
flage = false;
break;
default:
printf("无效的选择\n");
break;
}
}
}
break;
//首先向服务器发送“DOWNLOAD”,
//然后提示用户输入要下载的文件路径,发送文件路径到服务器,接收服务器发送的文件大小。
//如果文件大小大于0,提示用户输入本地保存路径,打开文件以写入二进制数据。然后接收文件数据,
//如果接收到的数据长度大于0,将数据写入文件,否则如果接收到的数据长度为0,说明连接已经关闭,
//如果接收到的数据长度小于0,说明接收数据时发生错误。最后关闭文件,如果接收到的字节数等于文件大小,说明文件下载成功,否则文件下载未完成。
case 3:
// 下载文件
send_message(clientSocket, "DOWNLOAD");
// 接收加密的密码
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
printf("收到加密密码: %s\n", buffer);
printf("请解密密码并输入: ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = '\0';
// 发送解密后的密码
send_message(clientSocket, buffer);
// 接收密码验证结果
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
if (strcmp(buffer, "PASSWORD_CORRECT") == 0) {
printf("密码正确。继续进行文件下载。\n");
printf("请输入要下载的文件路径: ");
fgets(filePath, MAX_PATH, stdin);
filePath[strcspn(filePath, "\n")] = '\0';
send_message(clientSocket, filePath);
// 接收文件大小
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
long fileSize = atol(buffer);
if (fileSize > 0) {
printf("请输入保存文件的本地路径: ");
fgets(filePath, MAX_PATH, stdin);
filePath[strcspn(filePath, "\n")] = '\0';
fp = fopen(filePath, "wb");
if (fp == NULL) {
printf("无法创建本地文件。\n");
break;
}
// 接收文件数据
long bytesReceived = 0;
while (bytesReceived < fileSize) {
ret = recv(clientSocket, buffer, BUFFER_SIZE, 0);
if (ret > 0) {
fwrite(buffer, 1, ret, fp);
bytesReceived += ret;
} else if (ret == 0) {
// 连接已正常关闭
break;
} else {
// 发生错误
printf("接收失败: %d\n", WSAGetLastError());
break;
}
}
fclose(fp);
if (bytesReceived == fileSize) {
printf("文件下载成功。\n");
} else {
printf("文件下载不完整。\n");
}
} else {
printf("服务器上找不到该文件。\n");
}
}
} else {
printf("密码错误。文件下载已中止。\n");
}
}
}
break;
//这部分代码处理用户选择5的情况,即聊天。首先向服务器发送"CHAT",然后进入一个无限循环,在循环中提示用户输入消息,
//发送消息到服务器,接收服务器的响应,如果响应的长度大于0,打印服务器的消息,否则退出循环。
case 4:
// 聊天
printf("输入0000,退出聊天\n");
send_message(clientSocket, "CHAT");
while (1) {
printf("输入您的消息:" );
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = '\0';
if (strcmp(buffer, "0000") == 0) {
send_message(clientSocket, "EXIT_CHAT");
break; // 退出聊天循环
}
send_message(clientSocket, buffer);
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
printf("Server: %s\n", buffer);
} else {
break;
}
}
break;
case 5:
send_message(clientSocket, "EXIT");
cleanup(clientSocket);
return 0;
default:
printf("无效的选择。\n");
break;
}
}
}
服务端:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string.h>
//winsock2.h和ws2tcpip.h是Windows套接字编程的头文件。
//编译器预处理器命令。定义了两个宏:BUFFER_SIZE和MAX_PATH。
//BUFFER_SIZE用于定义接收和发送缓冲区的大小,
//MAX_PATH用于定义文件路径的最大长度。定义了一个全局变量filePath,用于存储文件路径。
#define BUFFER_SIZE 1024
#define MAX_PATH 260
char filePath[MAX_PATH];
//定义了一个cleanup函数,用来关闭套接字并清理Winsock环境。
void cleanup(SOCKET socket) {
closesocket(socket);
WSACleanup();
}
//定义了一个send_message函数,用于发送消息。它接收套接字和要发送的消息作为参数,计算消息的长度,然后使用send函数发送它。
int send_message(SOCKET socket, const char *message) {
int len = strlen(message);
return send(socket, message, len, 0);
}
//定义了一个receive_message函数,用于接收消息。它接收套接字、用于存储接收到的数据的缓冲区和缓冲区的大小作为参数。首先调用recv函数接收数据,
//然后如果接收到的数据长度大于0,就在缓冲区的末尾添加一个空字符,以确保数据是一个正确的字符串。
int receive_message(SOCKET socket, char *buffer, int bufferSize) {
int ret = recv(socket, buffer, bufferSize - 1, 0); //0:这个参数是 recv 函数的 flags 参数。
//flags 可以用来指定接收操作的行为。当 flags 设置为 0时,
//表示没有特殊的行为,recv 将执行一个标准的阻塞式接收操作,这意味着它将等待直到有数据可读或者发生错误
if (ret > 0) {
buffer[ret] = '\0'; // Null-terminate the string
}
return ret;
}
//main函数的开始部分。定义了一些变量,包括用于存储Winsock数据的wsaData,服务器套接字serverSocket,客户端套接字clientSocket,
//服务器地址serverAddr,客户端地址clientAddr,客户端地址的长度clientAddrLen,函数的返回值ret,用于存储发送和接收数据的缓冲区buffer,
//和用于文件操作的文件指针fp。
int main() {
WSADATA wsaData;
SOCKET serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
int clientAddrLen, ret;
char buffer[BUFFER_SIZE];
FILE *fp;
//这部分代码初始化Winsock。首先使用WSAStartup函数,如果返回值不为0,说明初始化失败,打印错误信息并返回1。
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed: %d\n", WSAGetLastError());
return 1;
}
//这部分代码创建服务器套接字。首先使用socket函数,如果返回值为INVALID_SOCKET,说明套接字创建失败,打印错误信息,清理Winsock环境并返回1。
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
printf("Socket creation failed: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//这部分代码设置服务器地址。使用inet_addr函数将IP地址从点分十进制字符串转换为网络字节序的整数。
//然后使用htons函数将端口号从主机字节序转换为网络字节序。
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // use inet_addr instead of inet_pton
serverAddr.sin_port = htons(8000);
//这部分代码将套接字绑定到地址。使用bind函数,如果返回值为SOCKET_ERROR,说明绑定失败,打印错误信息,关闭套接字,清理Winsock环境并返回1。
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
printf("绑定失败: %d\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
//这部分代码让套接字开始监听连接。使用listen函数,如果返回值为SOCKET_ERROR,说明监听失败,打印错误信息,关闭套接字,清理Winsock环境并返回1。
if (listen(serverSocket, 5) == SOCKET_ERROR) {
printf("Listen failed: %d\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
printf("Server is listening on port 8000...\n");
while (1) {
//主循环:服务器进入一个无限循环,等待客户端连接。
//接受客户端连接:使用 函数接受客户端连接,如果失败则打印错误信息并关闭服务器套接字和服务。accept
clientAddrLen = sizeof(clientAddr);
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (clientSocket == INVALID_SOCKET) {
printf("Accept failed: %d\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
printf("Client connected.\n");
//处理客户端请求:进入另一个无限循环,处理客户端发送的请求。
//接收消息:使用 函数接收客户端消息,如果接收失败或客户端断开连接,则关闭客户端套接字并退出内层循环。receive_message
while (1) {
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret <= 0) {
printf("Client disconnected.\n");
closesocket(clientSocket);
break;
}
//EXIT 命令:如果客户端发送 “EXIT”,则关闭客户端套接字并退出内层循环。
//READ 命令:如果客户端发送 “READ”,则打开指定文件并读取内容,然后发送给客户端。如果文件无法打开或文件大小超过缓冲区大小,则发送相应的错误信息。
if (strcmp(buffer, "EXIT") == 0) {
printf("Client disconnected.\n");
closesocket(clientSocket);
break;
} else if (strcmp(buffer, "READ") == 0) {
// Read file content
fp = fopen(filePath, "r");
if (fp == NULL) {
printf("Failed to open file: %s\n", filePath);
send_message(clientSocket, "Failed to open file");
} else {
// Read the entire file content
long fileSize;
fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
rewind(fp);
// Ensure buffer can hold the entire file content
if (fileSize >= BUFFER_SIZE) {
printf("File size exceeds buffer limit.\n");
send_message(clientSocket, "File size exceeds buffer limit");
} else {
fread(buffer, 1, fileSize, fp);
buffer[fileSize] = '\0'; // ensure string is null-terminated
send(clientSocket, buffer, fileSize, 0);
}
fclose(fp);
}
} else if (strcmp(buffer, "APPEND") == 0) {
// 追加文件内容
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
fp = fopen(filePath, "a"); // 使用追加模式打开文件
if (fp == NULL) {
printf("无法打开文件: %s\n", filePath);
send_message(clientSocket, "无法打开文件");
} else {
fprintf(fp, "\n%s", buffer); // 在新行追加内容
fclose(fp);
send_message(clientSocket, "文件内容已成功追加");
printf("文件 %s 的内容已被追加\n", filePath);
}
} else {
send_message(clientSocket, "接收追加内容失败");
}
}
else if (strcmp(buffer, "WRITE") == 0) { //WRITE 命令:如果客户端发送 “WRITE”,
//则接收客户端发送的文件内容,并写入指定文件。
//如果文件无法打开,则发送相应的错误信息。
// Modify file content
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
fp = fopen(filePath, "w"); //w特性如果文件不存在,它会创建一个新文件。
//如果文件已经存在,它会截断文件(即删除所有现有内容),然后从文件开头开始写入。
if (fp == NULL) {
printf("Failed to open file: %s\n", filePath);
send_message(clientSocket, "Failed to open file");
} else {
fwrite(buffer, 1, ret, fp);
fclose(fp);
send_message(clientSocket, "File content modified");
}
}
} else if (strcmp(buffer, "DOWNLOAD") == 0) {
// 生成并加密密码
char password[20];
char encrypted_password[20];
int shift = 3; // 凯撒加密的偏移量
printf("请输入文件下载密码: ");
fgets(password, sizeof(password), stdin);
password[strcspn(password, "\n")] = '\0';
// 凯撒加密
for (int i = 0; i < strlen(password); i++) {
if (isalpha(password[i])) {
char base = isupper(password[i]) ? 'A' : 'a';
encrypted_password[i] = (password[i] - base + shift) % 26 + base;
} else {
encrypted_password[i] = password[i];
}
}
encrypted_password[strlen(password)] = '\0';
// 发送加密后的密码给客户端
send_message(clientSocket, encrypted_password);
// 接收客户端发送的解密密码
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
if (strcmp(buffer, password) == 0) {
send_message(clientSocket, "PASSWORD_CORRECT");
// 处理文件下载请求
ret = receive_message(clientSocket, filePath, MAX_PATH);
if (ret > 0) {
fp = fopen(filePath, "rb");
if (fp == NULL) {
printf("无法打开文件: %s\n", filePath);
send_message(clientSocket, "0"); // 发送文件大小为0,表示文件不存在
} else {
// 获取文件大小
fseek(fp, 0, SEEK_END);
long fileSize = ftell(fp);
rewind(fp);
// 发送文件大小
sprintf(buffer, "%ld", fileSize);
send_message(clientSocket, buffer);
// 发送文件内容
while ((ret = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) {
send(clientSocket, buffer, ret, 0);
}
fclose(fp);
printf("文件已发送: %s\n", filePath);
}
}
} else {
send_message(clientSocket, "PASSWORD_INCORRECT");
}
}
} else if (strcmp(buffer, "CHAT") == 0) {
// Chat functionality
while (1) {
// Receive client message
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret <= 0) {
break;
}
if (strcmp(buffer, "EXIT_CHAT") == 0) {
break; // 退出聊天循环
}
printf("Client: %s\n", buffer);
// Server sends message
printf("Server: ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = '\0'; // 去除换行符
send_message(clientSocket, buffer);
}
} else if (strcmp(buffer, "SET_PATH") == 0) { //SET_PATH 命令:如果客户端发送 “SET_PATH”,则接收客户端发送的文件路径,并设置为当前文件路径。
// Handle SET_PATH command
ret = receive_message(clientSocket, buffer, BUFFER_SIZE);
if (ret > 0) {
strncpy(filePath, buffer, MAX_PATH - 1);
filePath[MAX_PATH - 1] = '\0'; // 去除换行符
printf("File path set to: %s\n", filePath);
send_message(clientSocket, "File path set");
}
} else {
printf("Unknown command: %s\n", buffer);
}
}
}
closesocket(serverSocket);
WSACleanup();
return 0;
}