目录
一、UDP广播通信
1、什么是广播
2、特点
3、广播地址
4、实现广播的过程(一定是使用UDP协议)
广播发送端
广播接收方
练习1: 把广播通信进行实现
发送端
接收端
二、UDP组播(群聊)
1、概念
2、组播特点
3、IP地址分类
特殊地址
4、接收端怎么接收组播消息? -->需要加入组播属性的套接字
5、组播通信的过程
发送端
接收端
发送端
接收端
sendto("你好",192.168.14.255);
int socketfd = socket(AF_INET,SOCK_DGRAM,0);
2、设置socketfd套接字文件描述符的属性为 广播 。(也就是允许发送广播数据包SO_BROADCAST -----》使用广播方式传送 int on=1;
setsockopt(sockfd , SOL_SOCKET,SO_BROADCAST,&on, sizeof(on));
3、发送数据 ,指定接收方为广播地址 struct sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(10000);
sendAddr.sin_addr.s_addr = inet_addr("192.168.14.255");//一定是广播地址,广播发送
sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&sendAddr,sizeof(sendAddr));
4、关闭 close();
int socketfd = socket(AF_INET,SOCK_DGRAM,0);
2、绑定(192.168.14.255)广播IP地址和端口号 (10000) 注意:绑定的端口必须和发送方指定的端口相同 struct sockaddr_in ownAddr;
ownAddr.sin_family = AF_INET;
ownAddr.sin_port = htons(10000);
//uint32_t htonl(uint32_t hostlong); 将 主机IP转为 网络IP
ownAddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY(0.0.0.0) 代表本机所有的地址
//inet_addr("192.168.63.255");
3、接收数据 recvfrom();
4、关闭 close();
#include
#include
#include
#include /* See NOTES */
#include
#include
#include
#include #define GUANG_IP "192.168.11.255"
#define GUANG_PORT 60001int main()
{//建立套接字int socket_fd = socket(AF_INET,SOCK_DGRAM,0);if(socket_fd < 0){perror("sokcet fail");return -1;}//设置广播属性int on=1;setsockopt(socket_fd , SOL_SOCKET,SO_BROADCAST,&on, sizeof(on)); //给广播地址发送数据struct sockaddr_in send_addr;send_addr.sin_family = AF_INET;send_addr.sin_port = htons(GUANG_PORT);send_addr.sin_addr.s_addr = inet_addr(GUANG_IP);//广播地址char buf[1024] = {0};while(1){ bzero(buf,sizeof(buf));scanf("%s",buf);//发送的是实际的长度sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&send_addr,sizeof(send_addr));}//关闭套接字close(socket_fd);
}
#include
#include
#include
#include /* See NOTES */
#include
#include
#include
#include #define GUANG_IP "192.168.11.255"
#define GUANG_PORT 60001int main()
{//建立套接字int socket_fd = socket(AF_INET,SOCK_DGRAM,0);if(socket_fd < 0){perror("sokcet fail");return -1;}//绑定广播地址struct sockaddr_in my_addr;my_addr.sin_family = AF_INET;my_addr.sin_port = htons(GUANG_PORT);my_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY本机任意IP地址--常用方法//send_addr.sin_addr.s_addr = inet_addr(GUANG_IP);//广播地址bind(socket_fd,(struct sockaddr *)&my_addr,sizeof(my_addr));char buf[1024] = {0};int ret;struct sockaddr_in recv_addr;socklen_t addrlen = sizeof(recv_addr);while(1){ bzero(buf,sizeof(buf));//清空缓冲区ret = recvfrom(socket_fd,buf,sizeof(buf),0,(struct sockaddr *)&recv_addr,&addrlen);char *ip = inet_ntoa(recv_addr.sin_addr);int port = ntohs(recv_addr.sin_port);printf("[ip:%s port:%d] buf:%s ret:%d\n",ip,port,buf,ret);}//关闭套接字close(socket_fd);
}
#define IP_ADD_MEMBERSHIP 加入组播
// usr/include/linux/in.h
struct ip_mreq {
struct in_addr imr_multiaddr; /* 多播组的IP地址 224.0.0.10/
struct in_addr imr_interface; /* 需要加入到多组的IP地址 192.168.53.134 */
};
struct ip_mreq vmreq;
3、设置组播ip(初始化 组播结构体) inet_pton(AF_INET,"224.0.0.10",&vmreq.imr_multiaddr); // 组播地址
inet_pton(AF_INET,"192.168.63.2",&vmreq.imr_interface); // 需要添加到组的ip
#ininclude
int inet_pton(int af, const char *src, void *dst);
参数: af : 你要选择哪一种协议族 IPV4 --》AF_INET 还是 IPV6--》AF_INET6 src:本地IP地址 dst:将本地IP地址转为网络IP地址存储到这里 作用: 将本地IP地址转为网络IP地址 4、加入组播属性(也就是设置这个套接字 可以接收组播信息) setsockopt(socketfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&vmreq,sizeof(vmreq));
5、绑定地址 struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[1]));
saddr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl(INADDR_ANY) 代表 主机所有的地址
bind(socketfd,(struct sockaddr *)&saddr,sizeof(saddr));
6、接收数据
recvfrom(......)
#include
#include
#include
#include /* See NOTES */
#include #include
#include /*
*发送端
*/#define GROUP_IP "224.0.0.10"
#define GROUP_PORT 60002int main()
{//建立套接字int socket_fd;socket_fd = socket(AF_INET,SOCK_DGRAM,0);if(socket_fd < 0){perror("socket fail");return -1;}//往组播地址发送数据struct sockaddr_in send_addr;send_addr.sin_family = AF_INET;send_addr.sin_port = htons(GROUP_PORT);send_addr.sin_addr.s_addr = inet_addr(GROUP_IP);bind(socket_fd,(struct sockaddr *)&send_addr,sizeof(send_addr)); //往组播地址发送数据char buf[1024] = {0};int ret;while(1){ bzero(buf,sizeof(buf));scanf("%s",buf);sendto(socket_fd,buf,strlen(buf),0,(struct sockaddr *)&send_addr,sizeof(send_addr));}//关闭套接字close(socket_fd);
}
#include
#include
#include
#include /* See NOTES */
#include #include
#include /*
* 接收端
*/#define GROUP_IP "224.0.0.10"
#define GROUP_PORT 60002int main()
{//建立套接字int socket_fd;socket_fd = socket(AF_INET,SOCK_DGRAM,0);if(socket_fd < 0){perror("socket fail");return -1;}//定义组播结构体struct ip_mreq vmreq;//添加组播地址inet_pton(AF_INET,"224.0.0.10",&vmreq.imr_multiaddr);//将自己的ip添加到到组播地址中inet_pton(AF_INET,"192.168.11.2",&vmreq.imr_interface);//设置组播属性到套接字中setsockopt(socket_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&vmreq,sizeof(vmreq));//绑定本机任意地址struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(60002);saddr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl(INADDR_ANY) 代表 主机所有的地址bind(socket_fd,(struct sockaddr *)&saddr,sizeof(saddr)); //接收数据struct sockaddr_in recv_addr;socklen_t addrlen = sizeof(recv_addr);char buf[1024] = {0};int ret;while(1){ memset(buf,0,sizeof(buf));ret = recvfrom(socket_fd,buf,sizeof(buf),0,(struct sockaddr *)&recv_addr,&addrlen);char *ip = inet_ntoa(recv_addr.sin_addr);int port = ntohs(recv_addr.sin_port);printf("[ip:%s port:%d] buf:%s ret:%d\n",ip,port,buf,ret); }//关闭套接字close(socket_fd);
}
上一篇:MySQL数据库基础知识
下一篇:如何判断一段程序是否是裸机程序?