linux 网络编程之广播

linux 网络编程之广播

转载:https://blog.csdn.net/qdlovecsj/article/details/8805483

广播方式主要是指使用UDP套接口发送数据,发送数据的目标地址不是普通的地址,而是所指定网络的广播地址。

什么是广播地址?是指IP地址中主机地址部分全为1的IP地址。

下面是一个广播发送简单流程图。
这里写图片描述

如何实现广播发送?

一般情况下使用sendto函数只能向非广播地址发送数据,如果要发送广播数据就必须要告诉内核,可以通过设置套接字属性为SO_BROADCAST来坐到这一点。

int on = 1;

setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

广播的缺点:

不管主机有没有程序在接收或者处理广播信息,广播信息一定会被网卡收到并提交给操作系统处理,所以会造成网络上数据流量增大,对不接收广播信息的主机造成一定的负担。

下面是一个简单的发送广播的程序。

服务端每隔3s发送一个广播信息,信息为系统当前的时间。
服务器端代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define LEN             256

void getTime(char *curTime)
{
    time_t tm;
    time(&tm);

    snprintf(curTime, LEN, "%s\n", ctime(&tm));
}

int main(int argc, char **argv)
{
    struct sockaddr_in peeraddr;
    int sockfd = 0;
    int on = 1;
    int num = 0;

    char msg[LEN] = {0};

    if (argc != 3)
    {
        printf("Usage:%s<IP address> <PORT>\n", argv[0]);
        return -1;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        printf("Create socket fails!\n");
        return -1;
    }

    //设置套接字为广播模式  SO_BROADCAST
    setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

    bzero(&peeraddr, sizeof(peeraddr));
    peeraddr.sin_family = AF_INET;
    if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0)
    {
        printf("IP address is error!\n");
        return -1;
    }
    peeraddr.sin_port = htons(atoi(argv[2]));

    for (;;)
    {
        getTime(msg);

        num = sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&peeraddr, sizeof(struct sockaddr_in));

        fflush(stdout);
        sleep(3);
    }

    close(sockfd);

    return 1;
    }
客户端程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define LEN                     256

int main(int argc, char **argv)
{
    struct sockaddr_in localaddr;
    int sockfd = 0;
    int num = 0;
    char msg[LEN] = {0};

    if (argc != 2)
    {
        printf("Usage: %s<PORT>\n", argv[0]);
        return -1;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        printf("Create socket fails!\n");
        return -1;
    }

    bzero(&localaddr, sizeof(localaddr));
    localaddr.sin_family = AF_INET;
    localaddr.sin_port = htons(atoi(argv[1]));
    localaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    int opt = SO_REUSEADDR;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    if (bind(sockfd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr_in)) < 0)
    {
        printf("bind fails!\n");
        return -1;
    }

    num = read(sockfd, msg, LEN);
    if (num <= 0)
    {
        printf("read message fails!\n");
        return -1;
    }

    msg[num] = '\0';

    printf("time:%s\n", msg);

    close(sockfd);

    return 1;
    }

下面是简单的运行情况:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/Travelerwz/article/details/82655292