ぉ沙皮狗的忧伤 发表于 2021-3-17 15:49:30

网络编程_5day_广播

本帖最后由 ぉ沙皮狗的忧伤 于 2021-3-18 17:01 编辑

一、概念
    数据包的发送方式只有一个接受方成为单播,如果同时发给局域网中的所有主机称为广播,只有用户使用UDP协议才能广播
    广播地址,以172.18.21.1网段为例,最大的主机地址172.18.21.255代表该网段的广播地址
   

二、send_bt.c代码讲解
1、添加头文件#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>2、建立数据报套接字,使用UDP
//建立数据报套接字
//参数1----地址族,网络地址族
//参数2----套接字类型,SOCK_DGRAM使用UDP
//参数3----protocol通常设置为0
//返回值---成功返回socket ID,出错返回-1
serfd = socket( AF_INET, SOCK_DGRAM, 0);
if(serfd < 0){
   perror("socket failed!\n");
   exit(1);
}3、打开广播
int on = 1;
//打开广播
//参数1----socket套接字描述符
//参数2----选项级别,SOL_SOCKET套接字级别上设置选项
//参数3----选项名,SO_BROADCAST开启进程发送广播消息
//参数4----存放选项值得缓冲区地址
//参数5----缓冲区长度
//返回值---成功返回0,失败返回-1
ret = setsockopt( serfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
if(ret < 0){
    perror("setsockopt failed!\n");
    exit(1);
}4、指定接收方IP,广播地址,端口
//指定接收方IP为广播地址和端口
struct sockaddr_in self;
bzero( &self, sizeof(self));

self.sin_family = AF_INET;                  //选择ipv4协议
self.sin_port = htons(9999);                   //端口
self.sin_addr.s_addr = inet_addr("172.18.21.255");   //广播地址
5、从键盘读取数据并发送过去
//写数据
while(1){
    bzero( buf, 128);
    fgets( buf, 128, stdin);

    //发送数据
    //参数1-----套接字
    //参数2-----待发送数据的缓冲区
    //参数3-----缓冲区长度
    //参数4-----调用方式标志位,一般为0,将会改变sendto发送的形式
    //参数5-----指向目的的套接字地址
    //参数6-----指向地址的长度
    //返回值----成功,发送字节数,失败返回SOCKET_ERROR
    ret = sendto( serfd, buf, strlen(buf), 0, (struct sockaddr *)&self, sizeof(self));
    if(ret < 0){
      perror("send failed!\n");
      exit(1);
    }
}
三、recv_bt.c代码讲解1、添加头文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>2、建立数据报套接字
//2、建立数据报套接字
//参数1----地址族,AF_INET网络地址族
//参数2----套接字类型,SOCK_DGRAM使用UDP
//参数3----procotol通常设置为0
//返回值---成功返回socket id,失败返回-1
serfd = socket( AF_INET, SOCK_DGRAM, 0);
3、绑定本机IP和指定端口
//绑定本机IP和指定端口
struct sockaddr_in self;
bzero( &self, sizeof(self));

self.sin_family = AF_INET;             //选择ipv4协议
self.sin_port = htons(9999);         //端口
self.sin_addr.s_addr = htonl(INADDR_ANY);   //内核自动绑定本地所有IP
   
ret = bind( serfd, (struct sockaddr *)&self, sizeof(self));
if(ret < 0){
      perror("bind failed!\n");
      exit(1);
}4、读数据char buf;
struct sockaddr_in cli;
bzero( &cli,sizeof(cli));

int len = sizeof(cli);

//读数据:广播数据和单播数据
while(1){

    bzero( buf, 1024);
    //接收数据
    //参数1-----套接字
    //参数2-----待发送数据的缓冲区
    //参数3-----缓冲区长度
    //参数4-----调用方式标志位,一般为0,将会改变recv接收的形式
    //参数5-----指向目的的套接字地址
    //参数6-----指向地址的长度
    //返回值----成功,接收字节数,失败返回SOCKET_ERROR
    ret = recvfrom( serfd, buf, 1023, 0, (struct sockaddr *)&cli, &len);
    if(ret < 0){
      perror("recvfrom failed!\n");
      exit(1);
    }

    printf("client ip = %s port = %d buf = %s\n", inet_ntoa(cli.sin_addr),\
      ntohs(cli.sin_port), buf);
}
四、使用gcc编译send_bt.c在Ubuntu上运行,使用交叉编译工具编译recv_bt.c在板卡上运行
测试



页: [1]
查看完整版本: 网络编程_5day_广播