Linux 35 網路程式設計多播socket選項實踐

2021-09-25 04:24:23 字數 4552 閱讀 7341

用法:

int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);

ip多播模型(vrrp):

#include #include #include #include #include #include #include #include #include #include #include #include #include #include /* 192.168.220.128 */

#define local_addr 0xc0a8dc80

/* 192.168.220.129 */

#define peer_addr 0xc0a8dc81

#define ipproto_vrrp 0x70

/* 224.0.0.18 */

#define mcast_addr 0xe0000012

#define mode_local 0

#define mode_peer 1

#define buffer_size 128

extern int errno;

int mode = 0; /* local or peer */

int sockfd = 0;

long int lasttime = 0;

int socketinit()

; if((sockfd = socket(af_inet, sock_raw, ipproto_vrrp)) < 0)

/* 設定非阻塞模式 */

fcntl(sockfd, f_setfl, o_nonblock);

/* 設定ttl */

on = 255;

if ((ret = setsockopt (sockfd, ipproto_ip, ip_multicast_ttl, (char *)&on, sizeof(int))) < 0)

/* 禁止組播包環迴 */

on = 0;

if ((ret = setsockopt (sockfd, ipproto_ip, ip_multicast_loop, (char *)&on, sizeof(int))) < 0)

/* 加入多播組,用於收包 */

mreq.imr_multiaddr.s_addr = htonl(mcast_addr);

#if 0

mreq.imr_inte***ce.s_addr = mode == mode_local ? htonl(local_addr) : htonl(peer_addr);

#else

mreq.imr_inte***ce.s_addr = htonl(inaddr_any);

#endif

if ((ret = setsockopt(sockfd, ipproto_ip, ip_add_membership, (char *)&mreq, sizeof(mreq))) < 0)

/* 攜帶介面資訊 */

on = 1;

if ((ret = setsockopt(sockfd, ipproto_ip, ip_pktinfo, (char *)&on, sizeof(int))) < 0)

/* 設定自定義ip頭,否則系統會自己封裝ip頭 */

on = 1;

if ((ret = setsockopt(sockfd, ipproto_ip, ip_hdrincl, (char *)&on, sizeof(int))) < 0)

return 0;

}int socketrcv(int fd)

; int recvlen = 0;

time_t rawtime;

time(&rawtime);

printf("%s",ctime(&rawtime));

/* 這裡簡單的用recv收ip包,還可以使用recvmsg將控制資訊(介面索引和位址)帶進來,前面設定了ip_pktinfo */

/*struct in_pktinfo ;*/

recvlen = recv(fd, recvbuf, buffer_size, 0);

if (recvlen <= 0)

recvbuf[recvlen] = 0; /* 結束符 */

printf("recv %d bytes from peer:%s\n",recvlen,recvbuf+20); /* raw socket收上來的包帶20位元組的ip頭 */

return 0;

}int socketsend(int fd)

; struct msghdr msg = ;

struct iovec iov[2] = ;

struct ip_mreq mreq = ;

struct iphdr ip_header;

struct in_addr addr = ;

char vrrp_pkt[32] = "vrrp pkt test only!!!!!!!!!!!!!";

char mac[6] = ;

int ret = 0;

if (fd <= 0)

/* 設定ip頭部 */

memset(&ip_header, 0, sizeof(struct iphdr));

ip_header.version = 4;

ip_header.ihl = (sizeof(struct iphdr) >> 2) & 0xf;

ip_header.tos = iptos_prec_internetcontrol;

ip_header.id = 0;

ip_header.frag_off = 0;

ip_header.ttl = 255;

ip_header.protocol = ipproto_vrrp;

ip_header.check = 0;

ip_header.tot_len = htons(sizeof(struct iphdr) + sizeof(vrrp_pkt));

ip_header.saddr = mode == mode_local ? htonl(local_addr) : htonl(peer_addr);

ip_header.daddr = htonl(mcast_addr);

/* 設定目的位址 */

dst_addr.sin_family = af_inet;

dst_addr.sin_addr.s_addr = htonl(mcast_addr);

/* 設定msg */

msg.msg_name = &dst_addr;

msg.msg_namelen = sizeof (dst_addr);

msg.msg_iov = iov;

msg.msg_iovlen = 2;

/* 設定緩衝區 */

iov[0].iov_base = (char *)&ip_header;

iov[0].iov_len = sizeof(struct iphdr);

iov[1].iov_base = (char *)vrrp_pkt;

iov[1].iov_len = sizeof(vrrp_pkt);

/* 設定多播出介面 */

addr.s_addr = mode == mode_local ? htonl(local_addr) : htonl(peer_addr);

if ((ret = setsockopt(sockfd, ipproto_ip, ip_multicast_if, (char *)&addr, sizeof(addr))) < 0)

#if 0

/* 設定發包源mac */

if ((ret = setsockopt(sockfd, sol_socket, so_sndsrcmac, (char *)&mac, sizeof(mac))) < 0)

#endif

if ((ret = sendmsg(sockfd, &msg, msg_dontwait)) < 0)

return 0;

}int send_timer()

return 0;

}int main(int argc,char **ar**)

/* 啟動local或者peer,local和peer主要用於在兩台機器上(ip位址不同)測試 */

if (memcmp(ar**[1], "local", strlen("local")) == 0)

else if (memcmp(ar**[1], "peer", strlen("peer")) == 0)

else

socketinit();

/* 主程序迴圈 */

while(1)

}/* 發包定時器 */

send_timer();

} return 0;

}

網路程式設計 Linux多播簡單實現

在測試多時先確定測試的介面 網絡卡 是否已經開啟多播功能,如下 圖.1其中running multicast表示開啟了多播功能,可用ifconfig命令開啟 多播資料傳送端 include include include include include include include include...

Linux網路程式設計 (2)網路程式設計基礎

一 ip位址 1 ip的概念 internet protocol 網路之間互連的協議 也就是為計算機網路相互連線進行通訊而設計的協議。在 網際網路中,它是能使連線到網上的所有計算機網路實現相互通訊的一套規則,規定了 計算機在網際網路上進行通訊時應當遵守的規則。任何廠家生產的計算機系統,只要遵守ip協...

Linux網路程式設計基礎 01 網路基礎知識

internet 冷戰 的產物 1957年10月和11月,前蘇聯先後有兩顆 sputnik 衛星上天 1958年美國 艾森豪威爾向美國國會提出建立darpa defense advanced research project agency 即國防部高階研究計畫署,簡稱arpa 1968年6月darp...