Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

Linux UDP 廣播通信實戰:C++ 發送與接收完整代碼示例

編輯:關於 Linux

UDP 廣播適用於局域網設備發現、集群心跳、日誌分發等場景。本文提供完整的 C++ 發送端/接收端代碼,涵蓋 Socket 選項設置、廣播地址綁定、錯誤處理與編譯運行指南。

核心概念

  • 廣播地址:255.255.255.255 (受限廣播) 或 192.168.1.255 (定向廣播,網段最後地址)
  • Socket 選項:SO_BROADCAST 必須啟用
  • 端口:雙方約定一致 (示例使用 6000)

發送端完整代碼

// udp_broadcast_sender.cpp
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main() {
    // 1. 創建 UDP Socket
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        perror("socket creation failed");
        return 1;
    }

    // 2. 啟用廣播選項
    int opt = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) < 0) {
        perror("setsockopt SO_BROADCAST failed");
        close(sock);
        return 1;
    }

    // 3. 配置目標地址 (廣播地址 + 端口)
    struct sockaddr_in broadcastAddr;
    memset(&broadcastAddr, 0, sizeof(broadcastAddr));
    broadcastAddr.sin_family = AF_INET;
    broadcastAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);  // 255.255.255.255
    broadcastAddr.sin_port = htons(6000);

    // 4. 發送循環
    const char* msg = "Hello Broadcast World!";
    socklen_t addrLen = sizeof(broadcastAddr);

    cout << "Starting UDP broadcast sender on port 6000..." << endl;
    
    while (true) {
        int sent = sendto(sock, msg, strlen(msg), 0, 
                         (struct sockaddr*)&broadcastAddr, addrLen);
        if (sent < 0) {
            perror("sendto failed");
        } else {
            cout << "Sent: " << msg << " (" << sent << " bytes)" << endl;
        }
        sleep(1);  // 每秒發送一次
    }

    close(sock);
    return 0;
}

接收端完整代碼

// udp_broadcast_receiver.cpp
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main() {
    // 1. 創建 UDP Socket
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        perror("socket creation failed");
        return 1;
    }

    // 2. 綁定本地地址 (任意 IP + 端口)
    struct sockaddr_in localAddr;
    memset(&localAddr, 0, sizeof(localAddr));
    localAddr.sin_family = AF_INET;
    localAddr.sin_addr.s_addr = htonl(INADDR_ANY);  // 0.0.0.0
    localAddr.sin_port = htons(6000);

    if (bind(sock, (struct sockaddr*)&localAddr, sizeof(localAddr)) < 0) {
        perror("bind failed");
        close(sock);
        return 1;
    }

    // 3. 接收循環
    char buffer[1024];
    struct sockaddr_in senderAddr;
    socklen_t senderAddrLen = sizeof(senderAddr);

    cout << "UDP broadcast listener started on port 6000..." << endl;

    while (true) {
        int received = recvfrom(sock, buffer, sizeof(buffer)-1, 0,
                               (struct sockaddr*)&senderAddr, &senderAddrLen);
        if (received < 0) {
            perror("recvfrom failed");
            continue;
        }

        buffer[received] = '\0';
        char senderIP[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &senderAddr.sin_addr, senderIP, INET_ADDRSTRLEN);
        
        cout << "Received from " << senderIP << ":" << ntohs(senderAddr.sin_port)
             << " - " << buffer << endl;
    }

    close(sock);
    return 0;
}

編譯與運行

# 編譯
g++ udp_broadcast_sender.cpp -o sender
g++ udp_broadcast_receiver.cpp -o receiver

# 運行 (需在同一局域網不同終端/機器)
./sender
./receiver

關鍵技術點解析

關鍵點說明
SO_BROADCAST必須在發送端設置,否則 sendto 返回 EACCES
INADDR_BROADCAST宏定義為 0xFFFFFFFF,即 255.255.255.255
INADDR_ANY綁定 0.0.0.0 接收所有網卡廣播
防火牆需放行 UDP 6000 端口:firewall-cmd --add-port=6000/udp
路由器廣播默認不跨網段,跨 VLAN 需配置廣播轉發

進階擴展

  • 多播替代廣播:IP_ADD_MEMBERSHIP 加入組播組,減少網絡擾民
  • 添加消息協議頭:魔數、版本、序列號、校驗和
  • 接收端多線程處理:epoll + 線程池
  • 發送端限流:令牌桶算法控制發送頻率

編譯優化

# 生產環境編譯標誌
g++ -O2 -Wall -Wextra -std=c++17 -pthread udp_broadcast_sender.cpp -o sender

UDP 廣播代碼簡潔高效,是局域網服務發現與狀態同步的利器。

Copyright © Windows教程網 All Rights Reserved