#include <tchar.h> #include <stdio.h> #include <winsock2.h> #include <stdlib.h>
#include <string.h>
#include <Ws2tcpip.h> #include #include #pragma comment(lib,"ws2_32.lib")

#define BUFFER_SIZE 2048 #define FILE_NAME_MAX_SIZE 512

using namespace std; string home = "client_home/";

bool sendAll(SOCKET socket, const char* buffer, int length) { int totalSent = 0; int bytesLeft = length; int bytesSent = 0;

while (totalSent < length)
{
    bytesSent = send(socket, buffer + totalSent, bytesLeft, 0);
    if (bytesSent == SOCKET_ERROR)
    {
        return false;
    }
    totalSent += bytesSent;
    bytesLeft -= bytesSent;
}

return true;

}

bool receiveAll(SOCKET socket, char* buffer, int length) { int totalReceived = 0; int bytesLeft = length; int bytesRead = 0;

while (totalReceived < length)
{
    bytesRead = recv(socket, buffer + totalReceived, bytesLeft, 0);
    if (bytesRead == SOCKET_ERROR || bytesRead == 0)
    {
        return false;
    }
    totalReceived += bytesRead;
    bytesLeft -= bytesRead;
}

return true;

}

int main(int argc, char* argv[]) { // 初始化WSA,使得程序可以调用windows socket WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(sockVersion, &wsaData) != 0) { return 0; }

// 创建client_socket,并检测是否创建成功
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ;
if (client_socket == INVALID_SOCKET) {
    //如果创建的socket无效,则结束程序
    perror("socket error !");
    return 0;
}

// 创建地址结构,server_addr,并设置端口和IP
sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
//要连接的服务器端口号 8888
server_addr.sin_port = htons(8888);
//指定服务器的地址127.0.0.1
PCWSTR src = TEXT("127.0.0.1");
InetPton(AF_INET, src, &server_addr.sin_addr.s_addr);

//将client_socket与地址server_addr建立连接
if (connect(client_socket, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)))
{
    perror("connect error !\n");
    return 0;
}

cout << "请输入要执行的指令(1为上传文件,2为下载文件,3为查看文件列表):" << endl;
string choice;
cin >> choice;

// 向服务器发送buffer中的数据 
if (sendAll(client_socket, choice.c_str(), BUFFER_SIZE) == false)
{
    perror("错误信息:发送指令失败!");
    exit(1);
}

// 上传文件
if (choice == "1")
{
    // 输入想上传的文件
    memset(buffer, 0, BUFFER_SIZE);
    cout << "请输入要上传的文件名,如test.txt:" << endl; 
    string filename;
    cin >> filename;
    sendAll(client_socket, filename.c_str(), filename.length());

    // 打开文件并读取文件数据 
    string f = home + filename;
    FILE* fp;
    errno_t F_ERR = fopen_s(&fp, f.c_str(), "rb");
    string stateNum;
    if (F_ERR != 0)
    {
        cout << "错误信息:未能找到该文件!" << endl;
        stateNum = "1";
        sendAll(client_socket, stateNum.c_str(), stateNum.length());
        exit(1);
    }

    stateNum = "2";
    sendAll(client_socket, stateNum.c_str(), stateNum.length());
    
    // 确认服务端状态,判断是否能开始传输文件
    char flag[2];
    if (receiveAll(client_socket, flag, 2) == false)
    {
        cout << "错误信息:服务端接收客户端状态失败!" << endl;
        exit(2);
    }
    
    cout << "客户端开始上传文件!" << endl;
    memset(buffer, 0, BUFFER_SIZE);

    int length = 0;
    // 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 
    while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
    {
        if (sendAll(client_socket, buffer, length) == false)
        {
            cout << "错误信息:文件上传失败!" << endl;
            break;
        }
        memset(buffer, 0, BUFFER_SIZE);
    }

    // 关闭文件 
    fclose(fp);
    cout << "文件上传成功!" << endl;
}

// 下载文件
else if (choice == "2")
{
    // 输入想下载的文件
    memset(buffer, 0, BUFFER_SIZE);

    cout << "请输入要下载的文件名,如test.txt:" << endl;
    cin >> buffer;
    char file_name[FILE_NAME_MAX_SIZE + 1];
    strncpy_s(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
    if (sendAll(client_socket, buffer, BUFFER_SIZE) == false)
    {
        perror("错误信息:发送文件名失败!");
        exit(1);
    }

    // 接收服务端的状态:成功找到要下载的文件或没能找到文件
    char stateNum[2];
    memset(stateNum, 0, 2);
    if (receiveAll(client_socket, stateNum, 2) == false)
    {
        cout << "错误信息:接收服务端状态失败!" << endl;
    }

    if (!strcmp(stateNum, "1"))
    {
        cout << "错误信息:服务端未找到该文件名!" << endl;
        exit(2);
    }

    // 准备写入文件
    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;
        exit(1);
    }

    // 从服务器接收数据到buffer中 
    // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止 
    memset(buffer, 0, BUFFER_SIZE);
    cout << "下载文件中..." << endl;
    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 << file_name << "下载成功!" << endl;
    fclose(fp);
}

else if (choice == "3")
{
    cout << "服务器文件列表:" << endl;
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);
    while (recv(client_socket, buffer, BUFFER_SIZE, 0) > 0)
    {
        cout << buffer << " ";
        memset(buffer, 0, BUFFER_SIZE);
    }
}

// 关闭socket、WSA 
closesocket(client_socket);
WSACleanup();
system("pause");
return 0;
#include tcharh#include stdioh#include winsock2h#include stdlibh #include stringh #include Ws2tcpiph#include iostream#includefstream#pragma commentlibws2_32lib#define BUFFER_SIZE 2048#define FILE_NA

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

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