首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

VC++ 進階網路程式設計:TCP 連接埠監視與資料轉發實作

     編輯:VC++

前言

本文展示如何使用 Winsock 2 實作 TCP 連接埠監聽、連線轉發與資料記錄功能。程式碼示範綁定特定 IP、設定 SO_REUSEADDR 實現連接埠重用、多執行緒處理連線、透過 127.0.0.1 轉發至真實服務並記錄雙向資料流。

注意:此類技術可用於網路除錯、安全稽核,亦可被濫用於攔截敏感資料。請勿用於非法用途,僅供學習研究參考。

核心功能架構

  1. 初始化 Winsock
  2. 建立 Socket、設定 SO_REUSEADDR、綁定指定 IP:80
  3. listen 進入監聽狀態
  4. 迴圈 accept 接受連線,每連線建立一執行緒處理
  5. 工作執行緒連接 127.0.0.1:80(真實服務)
  6. 雙向轉發資料並寫入日誌檔

完整原始碼

#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <fstream.h>

DWORD WINAPI ClientThread(LPVOID lpParam);

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("Usage: listen [your_ip]\nExample: listen 202.112.246.2\n");
        return 0;
    }

    WORD wVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    if (WSAStartup(wVersion, &wsaData) != 0)
    {
        printf("WSAStartup failed!\n");
        return -1;
    }

    SOCKADDR_IN saddr = {0};
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr(argv[1]); // 指定 IP,非 INADDR_ANY
    saddr.sin_port = htons(80);

    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET) { printf("socket failed!\n"); return -1; }

    BOOL val = TRUE;
    // 關鍵:允許連接埠重用
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val)) != 0)
    { printf("setsockopt SO_REUSEADDR failed!\n"); return -1; }

    if (bind(s, (SOCKADDR*)&saddr, sizeof(saddr)) == SOCKET_ERROR)
    { printf("bind failed! Error: %d\n", WSAGetLastError()); return -1; }

    listen(s, 2);
    printf("Listening on %s:80 ...\n", argv[1]);

    while (1)
    {
        SOCKADDR_IN caddr; int clen = sizeof(caddr);
        SOCKET sc = accept(s, (sockaddr*)&caddr, &clen);
        if (sc != INVALID_SOCKET)
        {
            DWORD tid;
            HANDLE hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)sc, 0, &tid);
            if (hThread) CloseHandle(hThread);
            else { printf("Thread create failed!\n"); break; }
        }
    }

    closesocket(s);
    WSACleanup();
    return 0;
}

DWORD WINAPI ClientThread(LPVOID lpParam)
{
    SOCKET ss = (SOCKET)lpParam; // 客戶端連線
    SOCKET sc;                   // 真實服務連線
    char buf[4096];
    SOCKADDR_IN saddr = {0};
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    saddr.sin_port = htons(80);

    sc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sc == INVALID_SOCKET) { closesocket(ss); return -1; }

    DWORD timeout = 100;
    setsockopt(sc, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
    setsockopt(ss, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

    if (connect(sc, (SOCKADDR*)&saddr, sizeof(saddr)) != 0)
    {
        printf("Connect to real service failed!\n");
        closesocket(sc); closesocket(ss);
        return -1;
    }

    ofstream logFile("port80log.txt", ios::app);
    if (!logFile) { closesocket(ss); closesocket(sc); return 0; }

    while (1)
    {
        // 客戶端 -> 真實服務
        int n = recv(ss, buf, sizeof(buf), 0);
        if (n > 0)
        {
            logFile << "\n== CLIENT -> SERVER =========================================\n";
            logFile.write(buf, n);
            send(sc, buf, n, 0);
        }
        else if (n == 0) break;

        // 真實服務 -> 客戶端
        n = recv(sc, buf, sizeof(buf), 0);
        if (n > 0)
        {
            logFile << "\n== SERVER -> CLIENT =========================================\n";
            logFile.write(buf, n);
            send(ss, buf, n, 0);
        }
        else if (n == 0) break;
    }

    logFile.close();
    closesocket(ss);
    closesocket(sc);
    return 0;
}

關鍵技術點解析

  • SO_REUSEADDR:允許重複綁定已處於 TIME_WAIT 狀態的連接埠,實現連接埠重用。
  • 指定 IP 而非 INADDR_ANY:避免干擾正常服務,將流量導向監聽程式再轉發。
  • SO_RCVTIMEO:設定接收逾時,避免 recv 永久阻塞。
  • 雙向轉發迴圈:依序處理雙向資料,並記錄至檔案供分析。
  • 執行緒模型:每連線一執行緒,簡單但高併發下可改用 IOCP。

安全性提醒

此程式展示了中間人攻擊的基本原理。實際部署時,正規服務應使用 TLS 加密傳輸,防止明文資料被攔截分析。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved