1. 程式人生 > >linux 網路程式設計之廣播

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;
    }

下面是簡單的執行情況:

這裡寫圖片描述