zoukankan      html  css  js  c++  java
  • UDP 收/发 广播包

    网络通信基础

    如果网络中两个主机上的应用程序要相互通信,其一要知道彼此的IP,其二要知道程序可监听的端口。因为同一主机上的程序使用网络是通过端口号来区分的。


    UDP Socket的使用过程:

    1. 初始化网络库

    2. 创建SOCK_DGRAM类型的Socket。

    3. 绑定套接字。

    4. 发送、接收数据。

    5. 销毁套接字。

    6. 释放网络库。


    广播数据包的原理:

    专门用于同时向网络中所有工作站进行发送的一个地址叫做广播地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址。如果你的IP为:192.168.1.39,子网掩码为:255.255.255.0,则广播地址为:192.168.1.255;如果IP为192.168.1.39,子网掩码为:255.255.255.192,则广播地址为:192.168.1.63。

    如果只想在本网络内广播数据,只要向广播地址发送数据包即可,这种数据包可以被路由,它会经由路由器到达本网段内的所有主机,此种广播也叫直接广播;如果想在整个网络中广播数据,要向255.255.255.255发送数据包,这种数据包不会被路由,它只能到达本物理网络中的所有主机,此种广播叫有限广播。


    使用UDP协议发送、接收广播包的过程。

    假如我们要向192.168.0.X,子网掩码为:255.255.255.0的子网中发送广播包。

    其步骤如下:

    1. 初始化Winsock库。

    2. 创建SOCK_DIRAM类型的Socket。

    3. 设置Socket的属性允许其广播。

    4. 发送数据包到192.168.0.255

    5. 接收自己广播的广播包。

    6. 关闭Socket

    7. 释放网络库。

    注意事项如下:

    1. 接收方一定要知道广播方的口号,然后绑定此端口号才能正确接收。

    2. 接收方的Socket不需要设置成广播属性。

    3. 绑定的IP不可以使用“127.0.0.1”,可以使用真实IP地址或者INADDR_ANY。否则接收失败。

    参考代码:

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    //*-----------变量,数据类型宏定义-------------------
    #define PORT 3387
    #define MAX 255

    int main(void)
    {
    int sockfd, ret;
    int size, len;
    int so_broadcast=1;
    struct sockaddr_in my_con;
    struct sockaddr_in cl_con;
    char snd[MAX] = "123456789";
    char rec[MAX];
    //创建socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)
    {
    perror("socket error! ");
    exit(1);
    }
    //创建套接口
    my_con.sin_family = AF_INET;
    my_con.sin_port = ntohs(PORT);
    my_con.sin_addr.s_addr = inet_addr("192.168.1.255");
    len = sizeof(struct sockaddr);
    setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));
    //绑定套接口
    if(bind(sockfd, (struct sockaddr *) &my_con, len) < 0)
    {
    perror("bind error! ");
    exit(1);
    }
    //数据传输处理
    ret = sendto(sockfd, snd, strlen(snd), 0, (struct sockaddr *) &my_con, len);
    if(ret < 0)
    {
    perror("send error! ");
    exit(1);
    }
    printf("发送广播数据:%s ",snd);
    size=sizeof(cl_con);
    ret = recvfrom(sockfd,rec,MAX,0,(struct sockaddr *)&cl_con,&size);
    rec[ret] = '';
    printf("接收广播数据:%s ",rec);
    close(sockfd);
    return 0;
    }

  • 相关阅读:
    java程序高CPU,如何直接定位(linux系统下命令行操作)
    HashMap源码解读(jdk1.8)
    mysql索引原理
    redis常见问题
    Bitmap算法
    list遍历时删除的坑
    接口和抽象类有什么区别?各在什么场景下使用?
    记录BigInteger犯过的一个错误
    CentOS7切换源
    map遍历性能记录
  • 原文地址:https://www.cnblogs.com/lidabo/p/4724909.html
Copyright © 2011-2022 走看看