winsock 收發廣播包


☛廣播包的概念

廣播包通常為了如下兩個原因使用:1 一個應用程序希望在本地網絡中找到一個資源,而應用程序對於該資源的地址又沒有任何先驗的知識。
2 一些重要的功能,例如路由要求把它們的信息發送給所有找到的鄰機。
被廣播信息的目的地址取決於這一信息將在何種網絡上廣播。Internet域中支持一個速記地址用於廣播-INADDR_BROADCAST。由於使
用廣播以前必須捆綁一個數據報套接口,所以所有收到的廣播消息都帶有發送者的地址和端口。

廣播通信是無連接的通信,通信前不需要建立連接。不需要listen和accept,但需要綁定一個socket用來接收廣播。

☛廣播包的發送
創建socket
設置socket,例如設置超時、允許廣播等
綁定socket。在使用廣播前必須綁定一個socket。這一步可有可無,如果沒有,系統自動綁定到一個未用端口。
發送廣播。廣播的端口號要和接收方綁定的端口號一致

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <string.h>

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

void autoCleanup()
{
    WSACleanup();
}

int _tmain(int argc, _TCHAR* argv[])
{

    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested=MAKEWORD(2,2);
    int ret;
    ret = WSAStartup(wVersionRequested,&wsaData);

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    int bc = 1;
    //允許發送廣播消息
    int so_broadcast = TRUE;
    ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&so_broadcast, sizeof(so_broadcast));
    
    sockaddr_in addr;
    addr.sin_family = AF_INET; //使用互聯網際協議,即IP協議
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
    addr.sin_port = htons(2526);

    //如果僅僅是發送廣播,這一步可有可無。沒有綁定也能發送廣播
    //ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));

    struct sockaddr_in b_addr;
    b_addr.sin_family = AF_INET;
    b_addr.sin_addr.S_un.S_addr =htonl(INADDR_BROADCAST);
    b_addr.sin_port = htons(2527);


    char buff[50] = "Hello, world!";
    while (1)
    {
        ret = sendto(sock, buff, strlen(buff), 0, (struct sockaddr*)&b_addr, sizeof(b_addr));

        printf("send... %d\n", WSAGetLastError());
        Sleep(3000);
    }

    closesocket(sock);
    atexit(autoCleanup);
    return 0;
}

☛接收廣播包
接收方一定要知道廣播方的端口號,然后綁定同樣的端口號才能正確接收。道理很簡單,如果不綁定到一個端口,它不知道到哪里接收數據。

// send.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <string.h>

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

void autoCleanup()
{
    WSACleanup();
}

int _tmain(int argc, _TCHAR* argv[])
{
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested=MAKEWORD(2,2);
    WSAStartup(wVersionRequested,&wsaData);

    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    //這個端口要和廣播方廣播端口一致
    addr.sin_port = htons(2527);

    bind(sock, (struct sockaddr *)&addr, sizeof(addr));

    struct sockaddr_in from;
    int len = sizeof(from);
    int ret;
    char buff[50];

    while (1)
    {
        ret = recvfrom(sock, buff, 49, 0, (struct sockaddr *)&from, &len);
        if (ret > 0)
        {
            buff[ret] = 0;
            printf("%s\n", buff);
            printf("%s %d\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
        }
    }

    closesocket(sock);
    atexit(autoCleanup);
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM