Windows多網絡卡環境接收組播包

2021-10-05 20:21:43 字數 4872 閱讀 8424

說明:本文僅針對ipv4

區域網發現技術有很多,常用組播(或稱為多播):一台裝置傳送組播包,其他裝置加入組播組,接收到組播包時即可知曉傳送端ip,接收端回應約定資料即可讓傳送端也得知這些接收端的ip。

ipv4的d類位址(224.0.0.0至239.255.255.255)是ipv4多播位址。d類位址的低28位構成多播組id(group id),整個32位位址則成為組位址(group address)。

224.0.0.1為all-hosts組,224.0.0.2是all-routers組。

224.0.0.0~224.0.0.255之間的位址(224.0.0.0/24)稱為鏈路區域性(link-local)多播位址,是為低階拓撲發現和維護協議保留。

一般應用程式使用239.0.0.0~239.255.255.255之間的位址,稱作可管理地劃分範圍的ipv4多播空間(administratively scoped ipv4 multicast space)(rfc2365)。

static

const

auto multicast_group_address =

"239.255.43.21"

;static

const

unsigned

short multicast_group_port =

45454

;static

const

auto local_ip =

"192.168.1.222"

;

winsock.h與winsock2.h的一些巨集定義如ip_add_membership使用了不同的值,因此須特別注意。這破問題我是在join gruop(setsockopt(sockfd, ipproto_ip, ip_add_membership...))始終失敗,後來檢查錯誤碼為10042 (wsaenoprotoopt),搜尋得知不可直接#include, 而需要

#include #include #include #pragma comment(lib, "ws2_32.lib")
具體可參考info: header and library requirement when set/get socket options at the ipproto_ip level

無需多提,僅需建立udp socket,將資料報傳送至d類位址的某個約定好的埠即可。

struct sockaddr_in addr =

;addr.sin_family = af_inet;

addr.sin_port =

htons

(multicast_group_port)

;addr.sin_addr.s_addr =

inet_addr

(multicast_group_address)

;int addr_len =

sizeof

(addr)

;char host[

1024]=

;gethostname

(host,

1024);

int msgno =0;

char msg[

1024]=

;while

(true)

else

sleep

(1000);

}

必須繫結並設定出口網絡卡,否則會使用系統網絡卡列表的第乙個,有可能不是與其他裝置同乙個區域網的網絡卡。

int sockfd =

socket

(af_inet, sock_dgram,0)

;if(-

1== sockfd)

int reuse =1;

if(setsockopt

(sockfd, sol_socket, so_reuseaddr,

(const

char*)

&reuse,

sizeof

(reuse)

)<0)

struct sockaddr_in addr =

;addr.sin_family = af_inet;

addr.sin_port =

htons

(multicast_group_port)

;addr.sin_addr.s_addr = inaddr_any;

int addr_len =

sizeof

(addr)

;int ret =

bind

(sockfd,

(struct sockaddr*

)&addr,

sizeof

(struct sockaddr));

if(-1

== ret)

unsigned

long if_addr =

inet_addr

(local_ip)

;ret =

setsockopt

(sockfd, ipproto_ip, ip_multicast_if,

(const

char*)

&if_addr,

sizeof

(if_addr));

if(-1

== ret)

char host[

1024]=

;gethostname

(host,

1024);

int msgno =0;

char msg[

1024]=

;addr.sin_addr.s_addr =

inet_addr

(multicast_group_address)

;while

(true)

else

sleep

(1000);

}

非常簡單,網上的demo也大多針對這種情況。

建立udp socket,繫結inaddr_any、約定的埠,加入組播組,接收即可。

int ret =0;

int sockfd =

socket

(af_inet, sock_dgram,0)

;if(-

1== sockfd)

int reuse =1;

if(setsockopt

(sockfd, sol_socket, so_reuseaddr,

(const

char*)

&reuse,

sizeof

(reuse)

)<0)

struct sockaddr_in localaddr =

;localaddr.sin_family = af_inet;

localaddr.sin_port =

htons

(multicast_group_port)

;localaddr.sin_addr.s_addr =

/*inet_addr(local_ip)*/

htonl

(inaddr_any)

;ret =

bind

(sockfd,

(struct sockaddr*

)&localaddr,

sizeof

(struct sockaddr));

if(-1

== ret)

/*設定是否支援本地回環接收*/

/*int loopback = 1;

ret = setsockopt(sockfd, ipproto_ip, ip_multicast_loop, (const char *)&loopback, sizeof(loopback));

if (-1 == ret) */

struct ip_mreq ipmr =

;ipmr.imr_inte***ce.s_addr =

/*inet_addr(local_ip)*/

(inaddr_any)

;ipmr.imr_multiaddr.s_addr =

inet_addr

(multicast_group_address)

;int len =

sizeof

(ipmr)

;ret =

setsockopt

(sockfd, ipproto_ip, ip_add_membership,

(char*)

&ipmr, len);if

(-1== ret)

/* now just enter a read-print loop */

char msgbuf[msgbufsize]

;int nbytes =0;

localaddr.sin_addr.s_addr =

inet_addr

(multicast_group_address)

;while(1

) msgbuf[nbytes]=0

;puts

(msgbuf)

;}

有些不同,加入組播組時若依然使用inaddr_any,則核心預設使用網路裝置列表的第乙個裝置,有可能並不是該區域網。因此,需要將inaddr_any替換為local_ip,即本裝置與其他互相發現的裝置所在區域網的網絡卡ip。

ipmr.imr_inte***ce.s_addr =

inet_addr

(local_ip)

;

以上所有原始碼可在獲取。

Nacos系列 6 Nacos多網絡卡環境配置

實際生產環境,存在多網絡卡,此時使用nacos可能會存在ip不正確問題,針對此情況,nacos服務端ip,客戶端註冊ip應該怎麼配置?當前部署為單機環境nacos,版本1.3.2 找到nacos配置檔案 新增配置項nacos.inetutils.ip address,設定固定ip,啟動發現,ip已註...

windows多網絡卡使用改進

在前面的文章 windows下使用多網絡卡 中,提到了如何在windows下面使用多個網絡卡,但是在使用過程中,發現預設路由一段時間後就會被系統增加為2條,這樣就會導致問題出現。原因沒有深究,可能是因為路由器的設定,或者系統本身會定時重新通過dhcp獲取ip。所以,使用了取巧的辦法,改寫了之前的批處...

boost asio指定網絡卡加入多播組

有兩塊網絡卡,要指定加入特定網絡卡的多播組。看了一下boost asio文件,例子中沒有指定網絡卡 boost asio ip udp socket socket io service boost asio ip address multicast address boost asio ip add...