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


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

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