UDP广播组播通信
广播通信方式
数据包发送方式只有一个接收方,称为单播
如果同时发送给局域网内所有主机,称为广播。
只有用户数据报(使用UDP协议)套接字才能广播。
广播发送流程:
1)、创建发送用户数据报套接字
2)、缺省创建的套接字不允许广播数据包,需要设置属性。//setsockopt() 可以设置套接字属性
3)、接受方地址定为广播地址
4)、指定端口信息
5)、发送数据包
6)、关闭套接字
发送流程代码实现:
数据包发送方式只有一个接收方,称为单播
如果同时发送给局域网内所有主机,称为广播。
只有用户数据报(使用UDP协议)套接字才能广播。
广播发送流程:
1)、创建发送用户数据报套接字
2)、缺省创建的套接字不允许广播数据包,需要设置属性。//setsockopt() 可以设置套接字属性
3)、接受方地址定为广播地址
4)、指定端口信息
5)、发送数据包
6)、关闭套接字
发送流程代码实现:
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
intmain()
{
//socket
intsendFd=socket(PF_INET,SOCK_DGRAM,0); //创建发送用户数据报套接字
if(sendFd<0)
{
perror("socket error!");
return-1;
}
printf("socket ok!\n");
//setsockopt
inton=1;
setsockopt(sendFd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));//setsockopt() 可以设置套接字属性
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999); //指定端口信息
recvAddr.sin_addr.s_addr=inet_addr("192.168.3.255");//接受方地址定为广播地址
//sendto
charbuf[1024]={0};
gets(buf);
sendto(sendFd,buf,sizeof(buf),0,(structsockaddr*)&recvAddr,sizeof(recvAddr));//数据发送
//close
close(sendFd);//关闭套接字
return0;
}
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
intmain()
{
//socket
intsendFd=socket(PF_INET,SOCK_DGRAM,0); //创建发送用户数据报套接字
if(sendFd<0)
{
perror("socket error!");
return-1;
}
printf("socket ok!\n");
//setsockopt
inton=1;
setsockopt(sendFd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));//setsockopt() 可以设置套接字属性
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999); //指定端口信息
recvAddr.sin_addr.s_addr=inet_addr("192.168.3.255");//接受方地址定为广播地址
//sendto
charbuf[1024]={0};
gets(buf);
sendto(sendFd,buf,sizeof(buf),0,(structsockaddr*)&recvAddr,sizeof(recvAddr));//数据发送
//close
close(sendFd);//关闭套接字
return0;
}
广播接收流程:
1)、创建接受用户数据报套接字
2)、绑定本机IP地址和端口号 //绑定的端口必须和发送方指定的端口相同
3)、等待接收数据
4)、关闭接收套接字
接受流程代码实现:
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
intmain()
{
//socket
intrecvFd=socket(PF_INET,SOCK_DGRAM,0); //创建接受用户数据报套接字
if(recvFd<0)
{
perror("socket error!");
return-1;
}
printf("socket ok!\n");
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999);
recvAddr.sin_addr.s_addr=htonl(INADDR_ANY);//绑定本机IP地址和端口号 绑定的端口必须和发送方指定的端口相同
//bind
intret=bind(recvFd,(structsockaddr*)&recvAddr,sizeof(recvAddr));
if(ret<0)
{
perror("bind error!");
return-1;
}
printf("bind ok!\n");
charbuf[1024]={0};
//recvfrom
recvfrom(recvFd,buf,sizeof(buf),0,NULL,NULL);//等待接收数据
printf("recv:%s\n",buf);
//close
close(recvFd);//关闭接收套接字
return0;
}
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
intmain()
{
//socket
intrecvFd=socket(PF_INET,SOCK_DGRAM,0); //创建接受用户数据报套接字
if(recvFd<0)
{
perror("socket error!");
return-1;
}
printf("socket ok!\n");
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999);
recvAddr.sin_addr.s_addr=htonl(INADDR_ANY);//绑定本机IP地址和端口号 绑定的端口必须和发送方指定的端口相同
//bind
intret=bind(recvFd,(structsockaddr*)&recvAddr,sizeof(recvAddr));
if(ret<0)
{
perror("bind error!");
return-1;
}
printf("bind ok!\n");
charbuf[1024]={0};
//recvfrom
recvfrom(recvFd,buf,sizeof(buf),0,NULL,NULL);//等待接收数据
printf("recv:%s\n",buf);
//close
close(recvFd);//关闭接收套接字
return0;
}
组播通信方式
单播方式只能发送给一个接收方
广播方式发送给所有主机。过多的广播会大量占用网络带宽,造成广播风暴,影响正常的通信
组播又称为多播,是一种折中的方式,只有加入某个多播组的主机才能就收到数据。
多播方式既可以发送给多个主机,又能避免像广播一样带来过多的负载(每台主机要到传输层才能判断广播包是否要处理)
组播发送流程:
1)、创建用户数据包套接字
2)、接收方地址指定为组播地址
3)、指定端口号信息
4)、发送数据包
5)、关闭套接字
广播方式发送给所有主机。过多的广播会大量占用网络带宽,造成广播风暴,影响正常的通信
组播又称为多播,是一种折中的方式,只有加入某个多播组的主机才能就收到数据。
多播方式既可以发送给多个主机,又能避免像广播一样带来过多的负载(每台主机要到传输层才能判断广播包是否要处理)
组播发送流程:
1)、创建用户数据包套接字
2)、接收方地址指定为组播地址
3)、指定端口号信息
4)、发送数据包
5)、关闭套接字
组播发送流程代码:
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
intmain()
{
//socket
intsendFd=socket(PF_INET,SOCK_DGRAM,0);//创建用户数据包套接字
if(sendFd<0)
{
perror("socket error!");
return-1;
}
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999); //指定端口号信息
recvAddr.sin_addr.s_addr=inet_addr("224.10.10.1");//接收方地址指定为组播地址
charbuf[1024]={0};
gets(buf);
//sendto
sendto(sendFd,buf,sizeof(buf),0,(structsockaddr*)&recvAddr,sizeof(recvAddr));//发送数据包
//close
close(sendFd);//关闭套接字
return0;
}
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
intmain()
{
//socket
intsendFd=socket(PF_INET,SOCK_DGRAM,0);//创建用户数据包套接字
if(sendFd<0)
{
perror("socket error!");
return-1;
}
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999); //指定端口号信息
recvAddr.sin_addr.s_addr=inet_addr("224.10.10.1");//接收方地址指定为组播地址
charbuf[1024]={0};
gets(buf);
//sendto
sendto(sendFd,buf,sizeof(buf),0,(structsockaddr*)&recvAddr,sizeof(recvAddr));//发送数据包
//close
close(sendFd);//关闭套接字
return0;
}
组播接收流程:
1)、创建用户数据报套接字
2)、加入多播组
3)、绑定本机IP地址和端口号(绑定的端口号必须和发送指定的端口号相同)
4)、等待接收数据
5)、关闭套接字
1)、创建用户数据报套接字
2)、加入多播组
3)、绑定本机IP地址和端口号(绑定的端口号必须和发送指定的端口号相同)
4)、等待接收数据
5)、关闭套接字
组播接受代码实现:
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
intmain()
{
//socket
intrecvFd=socket(PF_INET,SOCK_DGRAM,0);//创建用户数据报套接字
if(recvFd<0)
{
perror("socket error");
return-1;
}
printf("socket ok!\n");
//join in multicast group
structip_mreqmreq={0};
mreq.imr_multiaddr.s_addr=inet_addr("224.10.10.1");//加入多播组
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
setsockopt(recvFd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
//bind
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999);
recvAddr.sin_addr.s_addr=htonl(INADDR_ANY);//绑定本机IP地址和端口号(绑定的端口号必须和发送指定的端口号相同)
intret=bind(recvFd,(structsockaddr*)&recvAddr,sizeof(recvAddr));
if(ret<0)
{
perror("bind error!");
close(recvFd);
return-1;
}
//recvfrom
charbuf[1024]={0};
recvfrom(recvFd,buf,sizeof(buf),0,NULL,NULL);//等待接收数据
printf("recv %s\n",buf);
//close
close(recvFd);//关闭接收套接字
return0;
}
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
intmain()
{
//socket
intrecvFd=socket(PF_INET,SOCK_DGRAM,0);//创建用户数据报套接字
if(recvFd<0)
{
perror("socket error");
return-1;
}
printf("socket ok!\n");
//join in multicast group
structip_mreqmreq={0};
mreq.imr_multiaddr.s_addr=inet_addr("224.10.10.1");//加入多播组
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
setsockopt(recvFd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
//bind
structsockaddr_inrecvAddr={0};
recvAddr.sin_family=PF_INET;
recvAddr.sin_port=htons(9999);
recvAddr.sin_addr.s_addr=htonl(INADDR_ANY);//绑定本机IP地址和端口号(绑定的端口号必须和发送指定的端口号相同)
intret=bind(recvFd,(structsockaddr*)&recvAddr,sizeof(recvAddr));
if(ret<0)
{
perror("bind error!");
close(recvFd);
return-1;
}
//recvfrom
charbuf[1024]={0};
recvfrom(recvFd,buf,sizeof(buf),0,NULL,NULL);//等待接收数据
printf("recv %s\n",buf);
//close
close(recvFd);//关闭接收套接字
return0;
}