UDP单播和组播使用SO_REUSEADDR 测试结果
- UDP单播通信
A、B在同一台机器,网络中存在往A、B所在的机器的8888端口发送单播UDP数据
A:端口复用绑定在端口8888上
B:端口复用绑定在端口8888上
操作步骤:
(1)先启动A
(2)再启动B
(3)B退出
预期结果:
(1)A 正常接收数据
(2)B 正常接收数据,A收不到数据
(3)A 正常接收数据
A、B在同一台机器,网络中存在往A、B所在的机器的8888端口发送单播UDP数据
A:绑定在端口8888上
B:端口复用绑定在端口8888上
操作步骤:
(1)先启动A
(2)再启动B
(3)关闭A和B,先启动B再启动A
预期结果:
(1)A 正常接收数据
(2)B 启动失败,绑定端口失败
(3)B 启动正常,并正常接收数据,A绑定端口失败
- 组播通信
A、B在同一台机器,网络中存在往8888端口发送组播数据
A:端口复用绑定在端口8888上,并加入组播组
B:端口复用绑定在端口8888上,并加入组播组
操作步骤:
(1)先启动A
(2)再启动B
预期结果:
(1)A 正常接收数据
(2)A和B 正常接收数据
A、B在同一台机器,网络中存在两个往8888端口发送组播数据,组播地址是:224.0.0.100和224.0.0.101
A:端口复用绑定在端口8888上,并加入224.0.0.100组播组
B:端口复用绑定在端口8888上,并加入224.0.0.101组播组
操作步骤:
(1)先启动A
(2)再启动B
预期结果:
(1)A 接收到224.0.0.100组播组的组播数据,B收不到任何数据
(2)A和B 接收到224.0.0.100和224.0.0.101组播组的组播数据
A、B在同一台机器,网络中存在往8888端口发送组播数据
A:绑定在端口8888上
B:端口复用绑定在端口8888上
操作步骤:
(1)先启动A
(2)再启动B
(3)关闭A和B,先启动B再启动A
预期结果:
(1)A 正常接收数据
(2)B 启动失败,绑定端口失败
(3)B 启动正常,并正常接收数据,A绑定端口失败
- 组播和UDP单播通信
A、B、C、D在同一台机器,网络中存在往8888端口发送组播数据,同时存在往A、B、C、D所在的机器的8888端口发送单播UDP数据
A: UDP单播 端口复用绑定在端口8888上
C: 端口复用绑定在端口8888上,并加入组播组
操作步骤:
(1)先启动A
(2)再启动C
(3)C退出
预期结果:
(1)A 正常接收单播数据
(2)C 正常接收组播以及单播数据,A只能收到组播数据
(3)A 正常接收单播数据
A、B、C、D在同一台机器,网络中存在往8888端口发送组播数据,同时存在往A、B、C、D所在的机器的8888端口发送单播UDP数据
A: UDP单播 端口复用绑定在端口8888上
C: 端口复用绑定在端口8888上,并加入组播组
操作步骤:
(1)先启动C
(2)再启动A
(3)
1.先退出C
2.先退出A
预期结果:
(1)C 正常接收组播数据
(2)A 正常接收组播以及单播数据,C正常收到组播数据
(3)1. A正常接收单播数据 2.C 正常接收单播以及组播数据
/*
* *multicast_recv.c
* */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define MCAST_PORT 8888
#define MCAST_ADDR "224.0.0.100" /*一个局部连接多播地址,路由器不进行转发*/
#define LOCAL_ADDR "192.168.50.21" /*本机网卡地址*/
#define MCAST_INTERVAL 5 /*发送间隔时间*/
#define BUFF_SIZE 256 /*接收缓冲区大小*/
int main(int argc, char*argv[])
{
struct sockaddr_in local_addr; /*本地地址*/ int fd = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
if (fd == -1)
{
perror("socket()");
exit(1);
} int yes = 1;
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)
{
perror("Reusing ADDR failed");
exit(1);
} /*初始化本地地址*/
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(MCAST_PORT); /*绑定socket*/
int err = bind(fd,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
if(err < 0)
{
perror("bind()");
exit(1);
} /*设置回环许可*/
int loop = 1;
err = setsockopt(fd,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
if(err < 0)
{
perror("setsockopt():IP_MULTICAST_LOOP");
exit(1);
} /*加入多播组*/
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*本地网络接口为默认*/ /*将本机加入多播组*/
err = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
if (err < 0)
{
perror("setsockopt():IP_ADD_MEMBERSHIP");
exit(1);
} int times = 0;
int addr_len = sizeof(local_addr);
char buff[BUFF_SIZE];
int n = 0; /*循环接收多播组的消息,5次后退出*/
while(1)
{
memset(buff, 0, BUFF_SIZE); /*清空接收缓冲区*/ /*接收数据*/
n = recvfrom(fd, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr,&addr_len);
if( n== -1)
{
perror("recvfrom()");
}
/*打印信息*/
printf("Recv %dst message from server:%s\n", ++times, buff);
} /*退出多播组*/
err = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq)); close(fd);
return 0;
}
组播multicast_send.c:
/*
* *broadcast_server.c - 多播服务程序
* */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define MCAST_PORT 8888
#define MCAST_ADDR "224.0.0.100" /*一个局部连接多播地址,路由器不进行转发*/
#define MCAST_DATA "BROADCAST TEST DATA" /*多播发送的数据*/
#define MCAST_INTERVAL 1 /*发送间隔时间*/
int main(int argc, char*argv)
{
struct sockaddr_in mcast_addr;
int fd = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
if (fd == -1)
{
perror("socket()");
exit(1);
} memset(&mcast_addr, 0, sizeof(mcast_addr));/*初始化IP多播地址为0*/
mcast_addr.sin_family = AF_INET; /*设置协议族类行为AF*/
mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*设置多播IP地址*/
mcast_addr.sin_port = htons(MCAST_PORT); /*设置多播端口*/ /*向多播地址发送数据*/
while(1)
{
int n = sendto(fd,MCAST_DATA,sizeof(MCAST_DATA),0,(struct sockaddr*)&mcast_addr,sizeof(mcast_addr)) ;
if( n < 0)
{
perror("sendto()");
exit(1);
}
sleep(MCAST_INTERVAL); /*等待一段时间*/
} return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#define MCAST_PORT 8888
#define LOCAL_ADDR "192.168.50.21" /*本机网卡地址*/ #define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while (0) void echo_ser(int sock)
{
char recvbuf[1024] = {0};
struct sockaddr_in peeraddr;
socklen_t peerlen;
int i = 0; while (1)
{ peerlen = sizeof(peeraddr);
memset(recvbuf, 0, sizeof(recvbuf));
int n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&peeraddr, &peerlen);
if (n == -1)
{
if (errno == EINTR)
continue; ERR_EXIT("recvfrom error");
}
else if(n > 0)
{
printf("==>(%d)-%s\n",++i,recvbuf);
}
}
close(sock);
} int main(void)
{
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
ERR_EXIT("socket error"); struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MCAST_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); int yes = 1;
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)
{
perror("Reusing ADDR failed");
exit(1);
} if (bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
ERR_EXIT("bind error"); echo_ser(sock); return 0;
}
单播udp_send.c:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define MCAST_PORT 8888
#define LOCAL_ADDR "192.168.50.21" /*本机网卡地址*/
#define UDP_DATA "UDP TEST DATA" /*UDP发送的数据*/
#define UDP_INTERVAL 1 /*发送间隔时间*/ #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while(0) void echo_cli(int sock)
{
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MCAST_PORT);
servaddr.sin_addr.s_addr = inet_addr(LOCAL_ADDR); while (1)
{
int ret = sendto(sock, UDP_DATA, strlen(UDP_DATA), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
if( ret < 0)
{
perror("sendto()");
exit(1);
}
sleep(UDP_INTERVAL); /*等待一段时间*/
} close(sock);
} int main(void)
{
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
ERR_EXIT("socket"); echo_cli(sock); return 0;
}
UDP单播和组播使用SO_REUSEADDR 测试结果的更多相关文章
- netty的Udp单播、组播、广播实例+Java的Udp单播、组播、广播实例
网络上缺乏netty的udp的单播.组播案例,经过一番学习总结之后终于把这两个案例调通,下面把这两个案例的代码放在这里分享一下. 首先推荐博文: http://colobu.com/2014/10/2 ...
- RFC3918组播转发时延测试——网络测试仪实操
一.简介 1.RFC3918简介 历史 · 在1999年3月成为正式标准 功能 · 评测网络互连设备或网络系统的性能 · 网络设备: 交换机,路由器- 内容 · 定义了一整套测试方法,为不同厂家的设备 ...
- 从内核3.7版本开始,Linux就开始支持VXLAN 到了内核3.12版本,Linux对VXLAN的支持已经完备,支持单播和组播,IPv4和IPv6。
一.关于VXLAN VXLAN 是 Virtual eXtensible LANs 的缩写,它是对 VLAN 的一个扩展,是非常新的一个 tunnel 技术,在Open vSwitch中应用也非常多. ...
- Android为TV端助力:UDP协议(接收组播和单播)
private static String MulticastHost="224.9.9.98";private static int POST=19999;private sta ...
- Java单播、组播(多播)、广播的简单实现
简介 单播有TCP和UDP两种实现,组播(多播)和广播只有UDP一种实现.单播和广播基本一样,只是广播的数据包IP为广播IP. 单播 DatagramSocket和DatagramPacket 服 ...
- MAC 地址(单播、组播、广播地址分类)
简介 一个制造商在生产制造网卡之前,必须先向 IEEE 注册,以获取到一个长度为 24bit 的厂商代码,也称为 OUI(Organizationally-Unique Identifier).制造商 ...
- UDP广播,组播服务器
广播 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ ...
- ganglia组播和单播
ganglia快速开始向导(翻译自官方wiki) 发布于 2012 年 1 月 23 日 由 admin 2 comments发表评论 转自:http://cryinstall.com/?p=18 ...
- RFC3918组播组容量测试——网络测试仪实操
一.简介 1.RFC3918简介 历史 · 在1999年3月成为正式标准 功能 · 评测网络互连设备或网络系统的性能 · 网络设备: 交换机,路由器- 内容 · 定义了一整套测试方法,为不同厂家的设备 ...
随机推荐
- FTP下载文件
linux命令方式下载 step1: >>ftp ip port 根据提示输入用户名 根据提示输入用户密码 >>cd 目录(重要:一定要进入文件所在的目录) >>g ...
- 简述ConCurrentHashMap
HashMap: 从JDK1.2起,就有了HashMap,HashMap不是线程安全的,多线程操作时需要注意. CurrentHashMap: 在JDK1.5中,引入concurrent包,从此Map ...
- Java高级篇(三)——JDBC数据库编程
JDBC是连接数据库和Java程序的桥梁,通过JDBC API可以方便地实现对各种主流数据库的操作.本篇将介绍一下如何使用JDBC操作数据库(以MySQL为例). 一.JDBC JDBC制定了统一访问 ...
- ABP领域层知识回顾之---工作单元
1. 前言 在上一篇博文中(http://www.cnblogs.com/xiyin/p/6842958.html) 我们讲到了ABP领域层的仓储.这边博文我们来讲 工作单元.个人觉得比较重要.文 ...
- [测试题]wows
Description 山山最近在玩一款游戏叫战舰世界(steam 游戏太少了),他被大舰巨炮的魅力折服,于是山山开了一局游戏,这次发现目标是一艘战列舰新墨西哥级,舰桥很高,原本应该打在目标身后的圆形 ...
- [HNOI2004]树的计数
题目描述 输入输出格式 输入格式: 输入文件第一行是一个正整数n,表示树有n个结点.第二行有n个数,第i个数表示di,即树的第i个结点的度数.其中1<=n<=150,输入数据保证满足条件的 ...
- ●BZOJ 1531 [POI2005]Bank notes
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1531 题解: 单调队列优化多重背包DP (弱弱的我今天总算是把这个坑给填了...) 令V[i ...
- 2015 多校联赛 ——HDU5414()
Problem Description CRB has two strings s and t. In each step, CRB can select arbitrary character c ...
- hdu 5437Alisha’s Party(优先队列)
题意:邀请k个朋友,每个朋友带有礼物价值不一,m次开门,每次开门让一定人数p(如果门外人数少于p,全都进去)进来,当所有人到时会再开一次,每次都是礼物价值高的人先进. /*小伙伴最开始gg了,结果发现 ...
- 4999: This Problem Is Too Simple!
Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: C i x(0<=x<2^31) 表示将i节点的值改为x. Q i j x(0<=x<2^31 ...