socket編程(3)廣播 多播

來源:互聯網
上載者:User

廣播

廣播是指在一個區域網路中向所有的網上節點發送資訊。這是UDP串連的一種

廣播有一個廣播組,即只有一個廣播組內的節點才能收到發往這個廣播組的資訊。什麼決定了一個廣播組呢,就是連接埠號碼,區域網路內一個節點,如果設定了廣播屬性並監聽了連接埠號碼A後,那麼他就加入了A組廣播,這個區域網路內所有發往廣播連接埠A的資訊他都收的到。在廣播的實現中,如果一個節點想接受A組廣播資訊,那麼就要先將他綁定給地址和連接埠A,然後設定這個socket的屬性為廣播屬性。如果一個節點不想接受廣播資訊,而只想發送廣播資訊,那麼不用綁定連接埠,只需要先為socket設定廣播屬性後,向廣播位址INADDR_BROADCAST的A連接埠發送udp資訊即可。詳細的程式實現如下:

1.初始化

    WSAStartup(MAKEWORD(2,2),&wsad);

2.建立一個UDP的socket
    s=socket(AF_INET,SOCK_DGRAM,0);

3.如果這個socket希望收到資訊,則需要綁定地址和這組廣播的連接埠號碼,如果只是希望發送廣播資訊,則不需要這步

    SOCKADDR_IN udpAdress,sender;
    int senferAddSize=sizeof(sender);
    udpAdress.sin_family=AF_INET;
    udpAdress.sin_port=htons(11114);
    udpAdress.sin_addr.s_addr=inet_addr("10.11.131.32");
    bind(s,(SOCKADDR*)&udpAdress,sizeof(udpAdress));

//這樣這個節點即可收到區域網路內所有發往連接埠11114的廣播資訊

4.設定socket的屬性為廣播
    bool optval=true;
    setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*)&optval,sizeof(bool));

5.下面就可以使用recvfrom或sendto來收發廣播資訊了

這裡是接受,這是一個阻塞操作
            ret=recvfrom(s,data,1000,0,(SOCKADDR*)&sender,&senferAddSize);

這裡是像該廣播組發送資訊,注意發送的地址為廣播位址INADDR_BROADCAST,連接埠號碼為改組廣播的連接埠號碼11114

    SOCKADDR_IN dstAdd;
    dstAdd.sin_family=AF_INET;
    dstAdd.sin_port=htons(11114);
    dstAdd.sin_addr.s_addr=INADDR_BROADCAST;
    sendto(s,data(),totalbyte,0,(SOCKADDR*)&dstAdd,sizeof(SOCKADDR));

 

多播

多播與廣播不同,多播是指一條資訊向區域網路內有限幾個節點傳遞,而廣播是不管某個節點是否在制定組內,都會向這個節點發送廣播資訊,容易造成網路負擔嚴重。

多播的實現是靠多播組,在區域網路內,一個多播地址唯一的定義了一個多播組(連接埠號碼任意),可以使用的多播地址是有規定的,從224.0.0.0—239.255.255.255之間,但是其中的一些地址不能用,是用作特殊用途的:224.0.0.0 –224.0.0.2  224.0.1.1  224.0.0.9 224.0.1.24。一個節點如果想接受自某個多播組或向某個多播組發送資訊,必須首先加入多播組,然後給予UDP發送。下面是詳細的代碼實現。

1.初始化

    WSAStartup(MAKEWORD(2,2),&wsad);

2.這裡傳建一個用於多播通訊的socket,注意這個socket的參數為設定成多播
    s=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED);

3.將socket綁定到一個本地地址、連接埠,和廣播不同,在多播中,無論是發送還是接收端都必須綁定一個本地地址,這個地址就是多播通訊時處理資訊的連接埠
    udpAdress.sin_family=AF_INET;
    udpAdress.sin_port=htons(22222);
    udpAdress.sin_addr.s_addr=inet_addr("10.11.131.32");
    bind(s,(SOCKADDR*)&udpAdress,sizeof(udpAdress));

4.定義多播組的地址
    multiCastGroup.sin_family=AF_INET;
    multiCastGroup.sin_port=htons(1111);此處連接埠任意,每個節點的可以設定成不同的
    multiCastGroup.sin_addr.s_addr=inet_addr("224.0.0.3"); 此處需使用上面規定位址區段內的多播地址

5.加入這個多播組。注意這裡的函數返回了一個socket,這個socket不負責通訊,只是在脫離多播組時使用

    SOCKET sockM=WSAJoinLeaf(s,(SOCKADDR*)&multiCastGroup,sizeof(multiCastGroup),NULL,NULL,NULL,NULL,JL_BOTH);

6.下面使用recvfrom接受多播資訊,或者使用sendto發送多播資訊   

ret=recvfrom(s,data,1000,0,(SOCKADDR*)&sender,&senferAddSize);

sendto(s,data(),totalbyte,0,(SOCKADDR*)&multiCastGroup,sizeof(multiCastGroup));

7.最後關閉清理
    closesocket(sockM);
    closesocket(s);
    WSACleanup();

 

其他:

1)在多播組中,預設情況下一個發出多播資訊的節點也會收到自己發送的資訊,這稱為多播迴環,可以關閉多播迴環:

bool val=false;

setsocket(s,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)val,sizeof(val));

2)在多播時,通常要設定適當的TTL(TTL的值是多少,那麼多播資訊就可以經過多少路由器,每經過一個路由器,TTl的值自動減1):

int val=3;

setsocket(s,IPPROTO_IP,IP_MULTICAST_TTL,(char*)val,sizeof(int));

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.