C语言课设(远程文件控制传输)

远程文件控制
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;
}

 

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值