目录

一、UDP广播通信

1、什么是广播

2、特点

3、广播地址

4、实现广播的过程(一定是使用UDP协议)

广播发送端

广播接收方

练习1: 把广播通信进行实现

发送端

接收端

二、UDP组播(群聊)

1、概念

2、组播特点

3、IP地址分类

特殊地址 

4、接收端怎么接收组播消息? -->需要加入组播属性的套接字 

5、组播通信的过程

发送端

接收端

发送端

接收端

一、UDP广播通信

1、什么是广播

单播:数据包发送方式只有一个接受方

广播:同时发给局域网中的所有主机

2、特点

只有用户数据报套接字(使用UDP协议)才能广播

3、广播地址

以192.168.63.0网段为例:

.

.***.255 代表该网段的广播地址。发送给该地址的数据包被所有主机接收

比如我们当前教室的局域网段 是 192.168.63.0 ,那么广播地址就是 192.168.63.255

sendto("你好",192.168.14.255);

4、实现广播的过程(一定是使用UDP协议)

 

广播发送端

1、创建数据报套接字 UDP

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();

广播接收方

1、创建用户数据报套接字

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();

练习1: 把广播通信进行实现

发送端

#include

#include

#include

#include /* See NOTES */

#include

#include

#include

#include

#define GUANG_IP "192.168.11.255"

#define GUANG_PORT 60001

int 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 60001

int 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);

}

二、UDP组播(群聊)

1、概念

组播是介于单播与广播之间,在一个局域网内,将某些主机添加到组中,并设置一个组地址.我们

只需要将数据发送到组播地址即可,加入到该组的所有主机都能接收到数据

2、组播特点

        需要给组播设置IP

地址,该

IP

必须是

D

类地址

        只有UDP

才能设置组播

3、IP地址分类

IP地址 = 网络号 + 主机号

 

特殊地址 

4、接收端怎么接收组播消息? -->需要加入组播属性的套接字 

#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 */

};

5、组播通信的过程

 

发送端

1、创建UDP数据报套接字

2、发送数据,往组播地址(224.0.0.10 )里面发送数据

3、关闭

接收端

(要把接收端的IP地址加入到组播里面)

1、创建UDP数据报套接字

2、定义组播结构体

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 60002

int 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 60002

int 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);

}

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: