#include <tchar.h>#include <winsock2.h>#include <string.h>#include <Ws2tcpip.h>#include #include<io.h>#pragma comment(lib,"ws2_32.lib")#define BUFFER_SIZE 2048 // 定义文件缓冲区大小#define FILE_NAME_MAX_SIZE 512 // 定义文件名最大长度\using namespace std;\string home = "server_home/"; // 定义服务器存储文件的默认路径\void uploadFile(SOCKET client_socket);\void downloadFile(SOCKET client_socket);\void getFileList(SOCKET client_socket);\int main(int argc, char* argv[]){// 初始化WSA,使得程序可以调用windows socket\WORD sockVersion = MAKEWORD(2, 2);\WSADATA wsaData;\if (WSAStartup(sockVersion, &wsaData) != 0){\return 0;}// 创建监听用套接字,server_socket,类型是TCP,并检测是否创建成功\SOCKET server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\if (server_socket == INVALID_SOCKET) {//如果创建的socket无效,则结束程序\perror("socket error !\n");\return 0;}// 创建地址,server_addr,并设置端口和IP\sockaddr_in server_addr;\server_addr.sin_family = AF_INET;//端口号 8888\server_addr.sin_port = htons(8888);//INADDR_ANY表示本机任意IP地址\server_addr.sin_addr.S_un.S_addr = INADDR_ANY;//将socket与地址server_addr绑定\if (bind(server_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR){\perror("bind error !\n");\return 0;}//server_socket开始监听\if (listen(server_socket, 20) == SOCKET_ERROR){\perror("listen error !\n");\return 0;}\while (1){\cout << "等待连接..." << endl;// 定义客户端的socket和socket地址结构\SOCKET client_socket;\sockaddr_in client_addr;\int client_addr_length = sizeof(client_addr);// 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信 // accept函数会把连接到的客户端信息写到client_addr中 \client_socket = accept(server_socket, (SOCKADDR*)&client_addr, &client_addr_length);\if (client_socket == INVALID_SOCKET){\perror("Socket连接建立失败:\n");\continue;}\WCHAR IP_BUFFER[256] = TEXT("0");\InetNtop(AF_INET, &client_addr.sin_addr, IP_BUFFER, 256);\wcout << "Socket连接建立,客户端IP为" << IP_BUFFER << ",端口为:" << ntohs(client_addr.sin_port) << endl;; // 宽字符记得用宽字符的方式进行输出// 接受客户端请求的指令// recv函数接收数据到缓冲区buffer中 \char buffer[BUFFER_SIZE];\memset(buffer, 0, BUFFER_SIZE);\if (recv(client_socket, buffer, BUFFER_SIZE, 0) < 0){\perror("错误信息:接收客户端指令失败:\n");\break;}\char choice[2];\strncpy_s(choice, buffer, strlen(buffer) > 1 ? 1 : strlen(buffer));// 根据客户端的不同指令执行相应的操作\if (!strcmp(choice, "1")){\uploadFile(client_socket);}\else if (!strcmp(choice, "2")){\downloadFile(client_socket);}\else if (!strcmp(choice, "3")){\getFileList(client_socket);}// 关闭与客户端的连接 \closesocket(client_socket);}// 关闭监听用的socket \closesocket(server_socket);\WSACleanup();\return 0;}// 上传文件\void uploadFile(SOCKET client_socket){// 接收文件名\char buffer[FILE_NAME_MAX_SIZE + 1];\memset(buffer, 0, FILE_NAME_MAX_SIZE + 1);\if (recv(client_socket, buffer, FILE_NAME_MAX_SIZE, 0) < 0){\perror("错误信息:接收客户端文件名失败!\n");\return;}\char file_name[FILE_NAME_MAX_SIZE + 1];\memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);\strncpy_s(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));// 接收客户端的状态:成功找到要上传的文件或没能找到文件\char stateNum[2];\memset(stateNum, 0, 2);\string flag; // 服务端状态\if (recv(client_socket, stateNum, 2, 0) < 0){\cout << "错误信息:接收客户端状态失败!" << endl;\flag = "0";\send(client_socket, flag.c_str(), flag.length(), 0);\return;}// 输出客户端状态\if (!strcmp(stateNum, "1")){\cout << "错误信息:客户端未找到该文件名!" << endl;\return;}\flag = "1";\send(client_socket, flag.c_str(), flag.length(), 0);// 准备写入文件\string f = file_name;\f = home + f;\FILE* fp;\errno_t F_ERR = fopen_s(&fp, f.c_str(), "wb");\if (F_ERR != 0){\cout << "文件打开失败!" << endl;\return;}// 从服务器接收数据到buffer中 // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 \cout << "接收文件中..." << endl;\memset(buffer, 0, BUFFER_SIZE);\int length = 0;\while ((length = recv(client_socket, buffer, BUFFER_SIZE, 0)) > 0){\if (fwrite(buffer, sizeof(char), length, fp) < length){\cout << "文件写入失败!" << endl;\break;}\memset(buffer, 0, BUFFER_SIZE);}\cout << "文件接收成功!" << endl;\fclose(fp);}// 下载文件\void downloadFile(SOCKET client_socket){// 接收文件名\char buffer[FILE_NAME_MAX_SIZE + 1];\memset(buffer, 0, FILE_NAME_MAX_SIZE + 1);\if (recv(client_socket, buffer, FILE_NAME_MAX_SIZE, 0) < 0){\perror("接收客户端文件名失败!\n"); \return;}\char file_name[FILE_NAME_MAX_SIZE + 1];\memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);\strncpy_s(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));// 开始读取文件\string f = file_name;\f = home + f;\FILE* fp;\errno_t F_ERR = fopen_s(&fp, f.c_str(), "rb");\string stateNum;\if (F_ERR != 0){\cout << "错误信息:未能找到该文件!" << endl;\stateNum = "1";\send(client_socket, stateNum.c_str(), stateNum.length(), 0);\return;}\else{\stateNum = "2";\send(client_socket, stateNum.c_str(), stateNum.length(), 0);}\cout << "服务端开始传输文件!" << endl;\memset(buffer, 0, BUFFER_SIZE);\int length = 0;// 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 \while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0){\if (send(client_socket, buffer, length, 0) < 0){\cout << "错误信息:文件传输失败!" << endl;\break;}\memset(buffer, 0, BUFFER_SIZE);}// 关闭文件 \fclose(fp);\cout << "文件传输成功!" << endl;}// 获取文件列表\void getFileList(SOCKET client_socket){\string path = "C:\Users\72797\source\repos\计算机网络\Debug\server_home\";//文件句柄\long hFile = 0;//文件信息\struct _finddata_t fileinfo;\string p;\if ((hFile = _findfirst(p.assign(path).append("*").c_str(), &fileinfo)) != -1){\do{\p.assign(fileinfo.name);\if (p == "." || p == "..") continue; // 除本地目录和上级目录,排除\memset(buffer, 0, BUFFER_SIZE);\send(client_socket, p.c_str(), p.length(), 0);} while (_findnext(hFile, &fileinfo) == 0);_findclose(hFile);}}


原文地址: https://www.cveoy.top/t/topic/pF0Q 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录