UDP的一对多通信(广播)-----个人笔记

补充:

1、TCP通信采用一对一的通信模式。日常生活中的网络会议通知、广告、网络信息公告等功能,需要采用UDP实现一对多的群发功能。

        通过Internet实现群发功能的形式有两种:
(1)利用广播向子网中的所有客户发送消息,比如各类通知、单位公告、集体活动日程安排等:
(2)利用组播向Internet网上不同的子网发送消息,比如集团向其所属的公司或用户子网发布信息公告等。

        广播,就是想对局域网内所有的主机同时发送数据,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。广播IP地址:192168.1.255/1921681(-1)广播MAC 地址:255.255255.255

2、广播的特点:子网中未参加相应广播应用的所有主机都会受到广播影响。

3、向一个广播地址发送UDP数据报时所发生的步骤为:

        首先假设子网地址为192.168.34,该子网的广播地址为192168.34.255,此子网下有俩台IP地址分别为192.168.341和192168.34.2的主机

(1)广播时sendto向IP为192168.34.255端口为3333发送数据报,此IP数据报在以太网下会激活ARP将目的广播地址192.168.34.255映射成相应的以太网地址(物理地址),然后将目的地址为此地址的帧发出去

(2)这次IP为192168.341和192168342的主机接口都会和此广播地址匹配成功,直到该数据报进入UDP层时根据端口是否匹配才判断是否丢弃该数据,端口为3333的会保留该数据,否则将数据丢弃。
4、广播:根据定义,广播分组会去往子网上的所有主机,包括发送主机自身,广播的缺点:未参加广播的主机也会受到影响

5、关于setsockopt

int setsockopt(int sockfd , int level, int optname, void *optval, socklen_t *optlen);

函数功能:设置套接字描述符的属性。

参数:
sockfd:要设置的套接字描述符。
level:选项定义的层次。或为特定协议的代码(如IPv4,IPv6,TCP,SCTP),或为通用套接字代码(SOL_SOCKET)。
optname:选项名。level对应的选项,一个level对应多个选项,不同选项对应不同功能。
optval:指向某个变量的指针,该变量是要设置新值的缓冲区。可以是一个结构体,也可以是普通变量

(参数optval表示选项的值,是一个指向选项值的指针。具体来说,它的类型和长度与所设置的选项有关,不同的选项可能需要不同类型和长度的参数。下面举例说明几种常见的选项及其对应的optval参数:

  1. SO_REUSEADDR选项:用于允许重用本地地址,其optval参数类型为int,表示是否允许重用地址,通常取值为1或0。

  2. SO_KEEPALIVE选项:用于启用TCP的心跳机制,其optval参数类型为int,表示是否启用心跳机制,通常取值为1或0。

  3. TCP_NODELAY选项:用于禁用Nagle算法,其optval参数类型为int,表示是否禁用Nagle算法,通常取值为1或0。

  4. SO_SNDBUF和SO_RCVBUF选项:用于设置发送和接收缓冲区的大小,其optval参数类型为int,表示缓冲区的大小,单位为字节。)

optlen:optval的长度。

一、通信框架

二、示例代码

recv端

#include<stdio.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<sys/msg.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<fcntl.h>
#include<sys/stat.h>

int main()
{
        int recv_fd;
        struct sockaddr_in recv_addr,send_addr;
        socklen_t recv_len,send_len;
        char rdBuffer[64] = {0};

        recv_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if(recv_fd < 0)
        {
                perror("socket failed\n");
                exit(1);
        }
        printf("recv_fd:%d\n",recv_fd);

        recv_addr.sin_family = AF_INET;
        recv_addr.sin_port = htons(8090);//设定一个服务器的端口号
        recv_addr.sin_addr.s_addr =htons(INADDR_ANY);
        recv_len = sizeof(recv_addr);
        send_len = sizeof(send_addr);
        bind(recv_fd,(struct sockaddr *)&recv_addr,recv_len);
        while(1)
        {
                recvfrom(recv_fd,rdBuffer,64,0,(struct sockaddr *)&send_addr,&send_len);
                printf("%s\n",rdBuffer);
        }
        printf("recv over\n");
        close(recv_fd);
        return 0;
}

send端

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
        struct sockaddr_in broadcast_addr = {0};
        int send_fd;
        socklen_t broadcast_len;

        char rdBuffer[64] = {0};

        send_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if(send_fd < 0)
        {
                perror("socket failed\n");
                exit(1);
        }
        printf("send_fd:%d\n",send_fd);
        int on = 1;
        setsockopt(send_fd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));//允许发送广播数据包

        broadcast_addr.sin_family = AF_INET;
        broadcast_addr.sin_port = htons(8090);
        broadcast_addr.sin_addr.s_addr = inet_addr("192.168.56.255");
        broadcast_len = sizeof(broadcast_addr);

        int i = 5;
        while(i--)
        {
        sendto(send_fd,"helloworld",12,0,(struct sockaddr *)&broadcast_addr,broadcast_len);
        sleep(2);
        }
        close(send_fd);

        return 0;
}

四、结果

 

五、参考文献

(63条消息) setsockopt()函数详解_Linux冰岛的博客-CSDN博客

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值