用法:
ip多播模型(vrrp):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);
#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...