#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\treturn 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\t//如果创建的socket无效,则结束程序\n\t\tperror("socket error !\n");\n\t\treturn 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\tperror("bind error !\n");\n\t\treturn 0;\n\t}\n\n\t//server_socket开始监听\n\tif (listen(server_socket, 20) == SOCKET_ERROR)\n\t{\n\t\tperror("listen error !\n");\n\t\treturn 0;\n\t}\n\n\twhile (1)\n\t{\n\t\tcout << "等待连接..." << endl;\n\n\t\t// 定义客户端的socket和socket地址结构\n\t\tSOCKET client_socket;\n\t\tsockaddr_in client_addr;\n\t\tint client_addr_length = sizeof(client_addr);\n\n\t\t// 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信 \n\t\t// accept函数会把连接到的客户端信息写到client_addr中 \n\t\tclient_socket = accept(server_socket, (SOCKADDR)&client_addr, &client_addr_length);\n\t\tif (client_socket == INVALID_SOCKET)\n\t\t{\n\t\t\tperror("Socket连接建立失败:\n");\n\t\t\tcontinue;\n\t\t}\n\n\t\tWCHAR IP_BUFFER[256] = TEXT("0");\n\t\tInetNtop(AF_INET, &client_addr.sin_addr, IP_BUFFER, 256);\n\t\twcout << "Socket连接建立,客户端IP为" << IP_BUFFER << ",端口为:"\n\t\t\t<< ntohs(client_addr.sin_port) << endl;; // 宽字符记得用宽字符的方式进行输出\n\n\t\t// 接受客户端请求的指令\n\t\t// recv函数接收数据到缓冲区buffer中 \n\t\tchar buffer[BUFFER_SIZE];\n\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\tif (recv(client_socket, buffer, BUFFER_SIZE, 0) < 0)\n\t\t{\n\t\t\tperror("错误信息:接收客户端指令失败:\n");\n\t\t\tbreak;\n\t\t}\n\t\tchar choice[2];\n\t\tstrncpy_s(choice, buffer, strlen(buffer) > 1 ? 1 : strlen(buffer));\n\n\t\t// 客户端选择上传文件\n\t\tif (!strcmp(choice, "1"))\n\t\t{\n\t\t\t// 接收文件名\n\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\t\tif (recv(client_socket, buffer, BUFFER_SIZE, 0) < 0)\n\t\t\t{\n\t\t\t\tperror("错误信息:接收客户端文件名失败!\n");\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tchar file_name[FILE_NAME_MAX_SIZE + 1];\n\t\t\tmemset(file_name, 0, FILE_NAME_MAX_SIZE + 1);\n\t\t\t//\t\trecv(client_socket, buffer, BUFFER_SIZE, 0);\n\t\t\tstrncpy_s(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));\n\n\t\t\t// 接收客户端的状态:成功找到要上传的文件或没能找到文件\n\t\t\tchar stateNum[2];\n\t\t\tmemset(stateNum, 0, 2);\n\t\t\tstring flag; // 服务端状态\n\n\t\t\tif (recv(client_socket, stateNum, 2, 0) < 0)\n\t\t\t{\n\t\t\t\tcout << "错误信息:接收客户端状态失败!" << endl;\n\t\t\t\tflag = "0";\n\t\t\t\tsend(client_socket, flag.c_str(), flag.length(), 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\n\t\t\t// 输出客户端状态\n\t\t\tif (!strcmp(stateNum, "1"))\n\t\t\t{\n\t\t\t\tcout << "错误信息:客户端未找到该文件名!" << endl;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tflag = "1";\n\t\t\tsend(client_socket, flag.c_str(), flag.length(), 0);\n\n\t\t\t// 准备写入文件\n\t\t\tstring f = file_name;\n\t\t\tf = home + f;\n\t\t\tFILE* fp;\n\t\t\terno_t F_ERR = fopen_s(&fp, f.c_str(), "wb");\n\t\t\tif (F_ERR != 0)\n\t\t\t{\n\t\t\t\tcout << "文件打开失败!" << endl;\n\t\t\t\texit(1);\n\t\t\t}\n\n\t\t\t// 从服务器接收数据到buffer中 \n\t\t\t// 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 \n\t\t\tcout << "接收文件中..." << endl;\n\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\t\tint length = 0;\n\t\t\twhile ((length = recv(client_socket, buffer, BUFFER_SIZE, 0)) > 0)\n\t\t\t{\n\t\t\t\tif (fwrite(buffer, sizeof(char), length, fp) < length)\n\t\t\t\t{\n\t\t\t\t\tcout << "文件写入失败!" << endl;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\t\t}\n\n\t\t\tcout << "文件接收成功!" << endl;\n\t\t\tfclose(fp);\n\t\t}\n\n\t\t// 客户端选择下载文件\n\t\telse if (!strcmp(choice, "2"))\n\t\t{\n\t\t\t// 接收文件名\n\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\t\tif (recv(client_socket, buffer, BUFFER_SIZE, 0) < 0)\n\t\t\t{\n\t\t\t\tperror("接收客户端文件名失败!\n"); \n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tchar file_name[FILE_NAME_MAX_SIZE + 1];\n\t\t\tmemset(file_name, 0, FILE_NAME_MAX_SIZE + 1);\n\t\t\tstrncpy_s(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));\n\n\t\t\t// 开始读取文件\n\t\t\t//ifstream in("server_home/test.txt");\n\t\t\tstring f = file_name;\n\t\t\tf = home + f;\n\t\t\tFILE* fp;\n\t\t\terno_t F_ERR = fopen_s(&fp, f.c_str(), "rb");\n\t\t\tstring stateNum;\n\t\t\tif (F_ERR != 0)\n\t\t\t{\n\t\t\t\tcout << "错误信息:未能找到该文件!" << endl;\n\t\t\t\tstateNum = "1";\n\t\t\t\tsend(client_socket, stateNum.c_str(), stateNum.length(), 0);\n\t\t\t\texit(1);\n\t\t\t} \n\t\t\telse\n\t\t\t{\n\t\t\t\tstateNum = "2";\n\t\t\t\tsend(client_socket, stateNum.c_str(), stateNum.length(), 0);\n\t\t\t}\n\t\t\tcout << "服务端开始传输文件!" << endl;\n\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\n\t\t\tint length = 0;\n\t\t\t// 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 \n\t\t\twhile ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)\n\t\t\t{\n\t\t\t\tif (send(client_socket, buffer, length, 0) < 0)\n\t\t\t\t{\n\t\t\t\t\tcout << "错误信息:文件传输失败!" << endl;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\t\t}\n\n\t\t\t// 关闭文件 \n\t\t\tfclose(fp);\n\t\t\tcout << "文件传输成功!" << endl;\n\n\t\t}\n\n\t\t// 客户端选择查看文件列表\n\t\telse if (!strcmp(choice, "3"))\n\t\t{\n\t\t\tstring path = "C:\Users\72797\source\repos\计算机网络\Debug\server_home\" ;\n\t\t\t//文件句柄\n\t\t\tlong hFile = 0;\n\t\t\t//文件信息\n\t\t\tstruct _finddata_t fileinfo;\n\t\t\tstring p;\n\t\t\tif ((hFile = _findfirst(p.assign(path).append("*").c_str(), &fileinfo)) != -1)\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tp.assign(fileinfo.name);\n\t\t\t\t\tif (p == "." || p == "..") continue; // 除本地目录和上级目录,排除\n\t\t\t\t\n\t\t\t\t\tmemset(buffer, 0, BUFFER_SIZE);\n\t\t\t\t\n\t\t\t\t\tsend(client_socket, p.c_str(), p.length(), 0);\n\n\t\t\t\t} while (_findnext(hFile, &fileinfo) == 0);\n\t\t\t\t_findclose(hFile);\n\t\t\t}\n\n\t\t\t\n\t\t}\n\n\t\t\n\n\t\t// 关闭与客户端的连接 \n\t\tclosesocket(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/pF0q 著作权归作者所有。请勿转载和采集!

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