UNP学习_UDP广播服务器和客户端的实现

UNP学习_UDP广播和组播服务器实现

1.1 广播概述

  单播指的是一个进程只与另一个进程通信。TCP就只支持单播寻址,UDP和原始IP支持其他类型寻址。广播可以将UDP报文发送到子网内的全部节点(包括自己),是”一对所有“的通信模式。

  广播与组播的要点:
(1)组播支持在IPv4中是可选的,IPv6中是必须的
(2)IPv6不支持广播,IPv4中的程序移植到IPv6需要把广播改为组播
(2)广播和组播要求用与UDP和原始IP,不能用于TCP

下图是UNP书中P421给出的广播示例:
UNP
利用ifconfig命令可以看到广播地址Bcast:
在这里插入图片描述

1.2 UDP广播服务器示例代码:

// File Name: udp_server.c
// Author: AlexanderGan
// Created Time: 2020年08月11日 星期二 19时57分33秒

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/stat.h>

int main(int argc, char*argv[]){

    int fd = socket(AF_INET,SOCK_DGRAM,0);

    if(fd < 0){
        perror("socket error!\n");
        exit(1);
    }

    struct sockaddr_in serv_addr, client_addr;
    socklen_t serv_len = sizeof(serv_addr);
    socklen_t cli_len = sizeof(client_addr);
    
    memset(&serv_addr,0,serv_len);
    memset(&client_addr,0,cli_len);
    
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(1234);

    int ret = bind(fd,(struct sockaddr*)&serv_addr,serv_len);
    if(ret < 0){
        perror("bind error!\n");
        exit(1);
    }
    //初始化客户端信息
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(1111);//客户端需要绑定的端口
    inet_pton(AF_INET,"192.168.142.255",&client_addr.sin_addr.s_addr);
    
    //打开服务器广播权限
    int flag = 1;
    setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&flag,sizeof(flag));

    while(1){
        //持续给客户端广播数据
        static int num = 0;

        char buf[4096] = {0};
        sprintf(buf,"hello ,udp_id == %d\n",num++);

        int send_len = sendto(fd,buf,sizeof(buf),0,(struct sockaddr*)&client_addr,cli_len);
        if(send_len < 0){
            perror("send error!\n");
            exit(1);
        }

        printf("server send buf = %s\n",buf);
        sleep(1);

        /*char ip[64];
        printf("New Client IP : %s, port = %d\n",
                inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ip,sizeof(ip)),
                ntohs(client_addr.sin_port));
        sendto(fd,buf,strlen(buf)+1,0,(struct sockaddr*)&client_addr,cli_len);*/

    }
    close(fd);
return 0 ;
}

1.3 UDP广播客户端示例代码:

// File Name: udp_client.c
// Author: AlexanderGan
// Created Time: 2020年08月16日 星期日 19时06分28秒
// 广播客户端

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/stat.h>

int main(int argc, char*argv[]){

    int fd = socket(AF_INET,SOCK_DGRAM,0);

    if(fd < 0){
        perror("socket error!\n");
        exit(1);
    }
    //绑定IP和端口
    struct sockaddr_in serv_addr, client_addr;
    socklen_t serv_len = sizeof(serv_addr);
    socklen_t cli_len = sizeof(client_addr);
    
    memset(&client_addr,0,cli_len);
    client_addr.sin_family = AF_INET;    
    client_addr.sin_port = htons(1111);
    inet_pton(AF_INET,"0.0.0.0",&client_addr.sin_addr.s_addr);  

    int ret = bind(fd,(struct sockaddr*)&client_addr,cli_len);
    if(ret < 0){
        perror("bind error!\n");
        exit(1);
    }
    //通信
    while(1){
        char buf[1024];
        int recv = recvfrom(fd,buf,sizeof(buf),0,NULL,NULL);

        if(recv < 0) {
            perror("recv error!\n");
            break;
        }

        printf("client recv buf =%s\n",buf);
    }

    close(fd);
    return 0;
}

对发送接收函数不熟悉的同学可以看一下recvfrom函数原型sendto函数原型

1.4 广播的优缺点
优点:主机发送后,子网的所有主机都能接收到
缺点:同一子网的所有主机都要处理广播的数据报,若是UDP数据报则需要一直向上传递到UDP层,不需要这些数据报的主机如果在运行需要高速率处理的应用则容易带来过度的处理负担。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值