《TCP/IP网络编程》第14章 多播与广播

92 篇文章 19 订阅
34 篇文章 3 订阅

多播

多播(Multicast)基于UDP,UDP数据传输以单一目标进行,多播数据同时传递到加入(注册)特定组的大量主机(同时向多个主机传递数据)。

多播的数据传输特点:

  • 多播服务器端针对特定多播组,只发送一次数据。
  • 该组内所有客户端都会收到数据。
  • 多播组数可在IP地址范围内任意增加。
  • 加入特定组即可接收发往该多播组的数据。

多播组是D类IP地址(224.0.0.0~239.255.255.255.255)

多播主要用于多媒体数据的实时传播,不少路由器不支持多播,即使支持也因网络拥堵问题故意阻断多播。隧道(Tunneling)技术可在不支持多播的路由器中完成多播通信。

TTL(Time to Live,生存时间)

决定数据包传递距离的主要因素,TTL用整数表示,每经过一个路由器就减1,变为0时,数据包无法传递,被销毁。

int send_sock;
int time_live=64;

send_sock=socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live));

加入多播组

int recv_sock;
struct ip_mreq join_adr;


recv_sock=socket(PF_INET, SOCK_DGRAM, 0);

join_adr.imr_multiaddr.s_addr="多播组地址信息";
join_adr.imr_interface.s_addr="加入多播组的主机地址信息";

setsockopt(send_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr));

struct ip_mreq {
	struct in_addr imr_multiaddr;//加入的组IP地址
	struct in_addr imr_interface;//主机IP地址,可使用INADDR_ANY
}

实现多播

14.news_sender_mul_linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define IP "224.1.1.2"
#define PORT 9999
#define TTL 64
#define BUF_SIZE 30

void error_handling(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    int send_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (send_sock == -1)
        error_handling("socket() error");

    int opt = 1;
    if (setsockopt(send_sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
        error_handling("setsockopt() error");

    int time_live = TTL;
    if (setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live)) == -1)
        error_handling("setsockopt() error");

    socklen_t addr_size = sizeof(struct sockaddr_in);

    struct sockaddr_in mul_addr;
    memset(&mul_addr, 0, addr_size);
    mul_addr.sin_family = AF_INET;
    mul_addr.sin_addr.s_addr = inet_addr(IP); // Multicast IP
    mul_addr.sin_port = htons(PORT);          // Multicast Port

    FILE *fp;
    if ((fp = fopen("14.news_sender_mul_linux.c", "r")) == NULL)
        error_handling("fopen() error");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE - 1, fp);
        sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&mul_addr, addr_size);
        usleep(200000);
    }
    fclose(fp);

    close(send_sock);

    return 0;
}

// gcc 14.news_sender_mul_linux.c -o 14.news_sender_mul_linux && ./14.news_sender_mul_linux
14.news_receiver_mul_linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define IP "224.1.1.2"
#define PORT 9999
#define BUF_SIZE 30

void error_handling(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    int recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (recv_sock == -1)
        error_handling("socket() error");

    int opt = 1;
    if (setsockopt(recv_sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
        error_handling("setsockopt() error");

    socklen_t addr_size = sizeof(struct sockaddr_in);
    struct sockaddr_in recv_addr;
    memset(&recv_addr, 0, addr_size);
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    recv_addr.sin_port = htons(PORT);
    if (bind(recv_sock, (struct sockaddr *)&recv_addr, addr_size) == -1)
        error_handling("bind() error");

    struct ip_mreq join_adr;
    join_adr.imr_multiaddr.s_addr = inet_addr(IP);
    join_adr.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr)) == -1)
        error_handling("setsockopt() error");

    while (1)
    {
        char buf[BUF_SIZE] = {0};
        int str_len = recvfrom(recv_sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    close(recv_sock);

    return 0;
}

// gcc 14.news_receiver_mul_linux.c -o 14.news_receiver_mul_linux && ./14.news_receiver_mul_linux
14.news_sr_mul_linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>

#define IP "224.1.1.2"
#define PORT 9999
#define TTL 64
#define BUF_SIZE 30

void error_handling(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

void *send_sock(void *arg)
{
    int sock = *(int *)arg;

    int time_live = TTL;
    if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live)) == -1)
        error_handling("setsockopt() error");

    socklen_t addr_size = sizeof(struct sockaddr_in);

    struct sockaddr_in mul_addr;
    memset(&mul_addr, 0, addr_size);
    mul_addr.sin_family = AF_INET;
    mul_addr.sin_addr.s_addr = inet_addr(IP); // Multicast IP
    mul_addr.sin_port = htons(PORT);          // Multicast Port

    sleep(1);
    
    FILE *fp;
    if ((fp = fopen("14.news_sr_mul_linux.c", "r")) == NULL)
        error_handling("fopen() error");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE - 1, fp);
        sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&mul_addr, addr_size);
        usleep(200000);
    }
    fclose(fp);

    close(sock);

    return NULL;
}

void *recv_sock(void *arg)
{
    int sock = *(int *)arg;

    socklen_t addr_size = sizeof(struct sockaddr_in);
    struct sockaddr_in recv_addr;
    memset(&recv_addr, 0, addr_size);
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    recv_addr.sin_port = htons(PORT);
    if (bind(sock, (struct sockaddr *)&recv_addr, addr_size) == -1)
        error_handling("bind() error");

    struct ip_mreq join_adr;
    join_adr.imr_multiaddr.s_addr = inet_addr(IP);
    join_adr.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr)) == -1)
        error_handling("setsockopt() error");

    while (1)
    {
        char buf[BUF_SIZE] = {0};
        int str_len = recvfrom(sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    close(sock);

    return (void *)0;
}

int main(int argc, char *argv[])
{
    int sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == -1)
        error_handling("socket() error");
    int opt = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
        error_handling("setsockopt() error");

    pthread_t t1;
    pthread_create(&t1, NULL, send_sock, (void *)&sock);
    pthread_t t2;
    pthread_create(&t2, NULL, recv_sock, (void *)&sock);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    return 0;
}

// gcc 14.news_sr_mul_linux.c -o 14.news_sr_mul_linux && ./14.news_sr_mul_linux

广播

多播即使在跨越不同网络的情况下,只要加入多播组就能接收数据。广播只能向同一网络中的主机传输数据。

广播方式

  • 直接广播
    网络地址不变,主机地址全部设置为1。
    例如192.12.34.255将向网络地址192.12.34的所有主机传输数据。
  • 本地广播
    IP地址限定为255.255.255.255。
    例如192.12.34的主机向255.255.255.255传输数据时,数据将向网络地址192.12.34的所有主机传输数据。

修改套接字属性

默认套接字会阻止广播

int send_sock;
int bcast=1;

send_sock=socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void *)&bcast, sizeof(bcast));

实现广播

14.news_sender_brd_linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define IP "255.255.255.255"
#define PORT 9999
#define BUF_SIZE 30

void error_handling(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    int send_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (send_sock == -1)
        error_handling("socket() error!");

    int opt = 1;
    if (setsockopt(send_sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
        error_handling("setsockopt() error!");

    int so_brd = 1;
    if (setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void *)&so_brd, sizeof(so_brd)) == -1)
        error_handling("setsockopt() error!");

    socklen_t addr_size = sizeof(struct sockaddr_in);

    struct sockaddr_in brd_addr;
    memset(&brd_addr, 0, addr_size);
    brd_addr.sin_family = AF_INET;
    brd_addr.sin_addr.s_addr = inet_addr(IP); // Broad IP
    brd_addr.sin_port = htons(PORT);          // Broad Port

    FILE *fp;
    if ((fp = fopen("14.news_sender_brd_win.c", "r")) == NULL)
        error_handling("fopen() error");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE, fp);
        sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&brd_addr, addr_size);
        usleep(200000);
    }
    fclose(fp);

    close(send_sock);

    return 0;
}

// gcc 14.news_sender_brd_linux.c -o 14.news_sender_brd_linux && ./14.news_sender_brd_linux
14.news_receiver_brd_linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define PORT 9999
#define BUF_SIZE 30

void error_handling(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    int recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (recv_sock == -1)
        error_handling("socket() error!");

    int opt = 1;
    if (setsockopt(recv_sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
        error_handling("setsockopt() error!");

    socklen_t addr_size = sizeof(struct sockaddr_in);
    struct sockaddr_in recv_addr;
    memset(&recv_addr, 0, addr_size);
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    recv_addr.sin_port = htons(PORT);
    if (bind(recv_sock, (struct sockaddr *)&recv_addr, addr_size) == -1)
        error_handling("bind() error!");

    while (1)
    {
        char buf[BUF_SIZE] = {0};
        int str_len = recvfrom(recv_sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    close(recv_sock);

    return 0;
}

// gcc 14.news_receiver_brd_linux.c -o 14.news_receiver_brd_linux && ./14.news_receiver_brd_linux
14.news_sr_brd_linux.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>

#define IP "255.255.255.255"
#define PORT 9999
#define TTL 64
#define BUF_SIZE 30

void error_handling(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

void *send_sock(void *arg)
{
    int sock = *(int *)arg;

    int so_brd = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *)&so_brd, sizeof(so_brd)) == -1)
        error_handling("setsockopt() error!");

    socklen_t addr_size = sizeof(struct sockaddr_in);

    struct sockaddr_in brd_addr;
    memset(&brd_addr, 0, addr_size);
    brd_addr.sin_family = AF_INET;
    brd_addr.sin_addr.s_addr = inet_addr(IP); // Broad IP
    brd_addr.sin_port = htons(PORT);          // Broad Port

    sleep(1);

    FILE *fp;
    if ((fp = fopen("14news_sr_brd_linux.c", "r")) == NULL)
        error_handling("fopen() error!");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE, fp);
        sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&brd_addr, addr_size);
        usleep(200000);
    }
    fclose(fp);

    close(sock);

    return NULL;
}

void *recv_sock(void *arg)
{
    int sock = *(int *)arg;

    socklen_t addr_size = sizeof(struct sockaddr_in);
    struct sockaddr_in recv_addr;
    memset(&recv_addr, 0, addr_size);
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    recv_addr.sin_port = htons(PORT);
    if (bind(sock, (struct sockaddr *)&recv_addr, addr_size) == -1)
        error_handling("bind() error!");

    while (1)
    {
        char buf[BUF_SIZE] = {0};
        int str_len = recvfrom(sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    close(sock);

    return (void *)0;
}

int main(int argc, char *argv[])
{
    int sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == -1)
        error_handling("socket() error!");
    int opt = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
        error_handling("setsockopt() error!");

    pthread_t t1;
    pthread_create(&t1, NULL, send_sock, (void *)&sock);
    pthread_t t2;
    pthread_create(&t2, NULL, recv_sock, (void *)&sock);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    return 0;
}

// gcc 14.news_sr_brd_linux.c -o 14.news_sr_brd_linux && ./14.news_sr_brd_linux

Windows实现

多播

14.news_sender_mul_win.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

// 224.0.0.0 ~ 239.255.255.255
#define IP "224.1.1.2"
#define PORT 9999
#define TTL 64
#define BUF_SIZE 30

void ErrorHanding(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    SOCKET hSendSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (hSendSock == INVALID_SOCKET)
        ErrorHanding("socket() error");

    int opt = 1;
    if (setsockopt(hSendSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0)
        ErrorHanding("setsockopt() error");

    int time_live = TTL;
    if (setsockopt(hSendSock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live)) < 0)
        ErrorHanding("setsockopt() error");

    int addr_size = sizeof(SOCKADDR);

    SOCKADDR_IN mulAdr;
    memset(&mulAdr, 0, addr_size);
    mulAdr.sin_family = AF_INET;
    mulAdr.sin_addr.s_addr = inet_addr(IP); // Multicast IP
    mulAdr.sin_port = htons(PORT);          // Multicast Port

    FILE *fp;
    if ((fp = fopen("14.news_sender_mul_win.c", "r")) == NULL)
        ErrorHanding("fopen() error!");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE - 1, fp);
        sendto(hSendSock, buf, strlen(buf), 0, (SOCKADDR *)&mulAdr, addr_size);
        Sleep(200);
    }
    fclose(fp);

    closesocket(hSendSock);

    WSACleanup();

    return 0;
}

// gcc 14.news_sender_mul_win.c -o 14.news_sender_mul_win -lws2_32 && ./14.news_sender_mul_win
14.news_receiver_mul_win.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

// 224.0.0.0 ~ 239.255.255.255
#define IP "224.1.1.2"
#define PORT 9999
#define BUF_SIZE 30

void ErrorHanding(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    SOCKET hRecvSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (hRecvSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    int opt = 1;
    if (setsockopt(hRecvSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0)
        ErrorHanding("setsockopt() error!");

    int addr_size = sizeof(SOCKADDR_IN);
    SOCKADDR_IN adr;
    memset(&adr, 0, addr_size);
    adr.sin_family = AF_INET;
    adr.sin_addr.s_addr = htonl(INADDR_ANY);
    adr.sin_port = htons(PORT);
    if (bind(hRecvSock, (struct sockaddr *)&adr, addr_size) == SOCKET_ERROR)
        ErrorHanding("bind() error!");

    struct ip_mreq join_adr;
    join_adr.imr_multiaddr.s_addr = inet_addr(IP);
    join_adr.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(hRecvSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr)) == SOCKET_ERROR)
        ErrorHanding("setsockopt() error!");

    while (1)
    {
        char buf[BUF_SIZE];
        int str_len = recvfrom(hRecvSock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    closesocket(hRecvSock);

    WSACleanup();

    return 0;
}

// gcc 14.news_receiver_mul_win.c -o 14.news_receiver_mul_win -lws2_32 && ./14.news_receiver_mul_win
14.news_sr_mul_win.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <pthread.h>
#include <unistd.h>

#define IP "224.1.1.2"
#define PORT 9999
#define TTL 64
#define BUF_SIZE 30

void ErrorHanding(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

void *sendSock(void *arg)
{
    SOCKET sock = *(SOCKET *)arg;

    int time_live = TTL;
    if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live)) < 0)
        ErrorHanding("setsockopt() error");

    int addr_size = sizeof(SOCKADDR_IN);

    SOCKADDR_IN mulAdr;
    memset(&mulAdr, 0, addr_size);
    mulAdr.sin_family = AF_INET;
    mulAdr.sin_addr.s_addr = inet_addr(IP); // Multicast IP
    mulAdr.sin_port = htons(PORT);          // Multicast Port

    /*
        if (connect(sock, (struct sockaddr *)&mulAdr, addr_size) == SOCKET_ERROR)
            ErrorHanding("connect() error");
    */

    sleep(1);

    FILE *fp;
    if ((fp = fopen("14.news_sr_mul_win.c", "r")) == NULL)
        ErrorHanding("fopen() error!");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE - 1, fp);
        sendto(sock, buf, strlen(buf), 0, (SOCKADDR *)&mulAdr, addr_size);
        // write(sock, buf, strlen(buf));
        Sleep(200);
    }
    fclose(fp);

    closesocket(sock);
    return NULL;
}

void *recvSock(void *arg)
{
    SOCKET sock = *(SOCKET *)arg;

    struct ip_mreq join_adr;
    join_adr.imr_multiaddr.s_addr = inet_addr(IP);
    join_adr.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr)) == SOCKET_ERROR)
        ErrorHanding("setsockopt() error!");

    while (1)
    {
        char buf[BUF_SIZE] = {0};
        int str_len = recvfrom(sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }
    return (void *)0;
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    int opt = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0)
        ErrorHanding("setsockopt() error!");

    int addr_size = sizeof(SOCKADDR_IN);
    SOCKADDR_IN localAdr;
    memset(&localAdr, 0, addr_size);
    localAdr.sin_family = AF_INET;
    localAdr.sin_addr.s_addr = htonl(INADDR_ANY);
    localAdr.sin_port = htons(PORT);
    if (bind(sock, (struct sockaddr *)&localAdr, addr_size) == SOCKET_ERROR)
        ErrorHanding("bind() error!");

    pthread_t t1;
    pthread_create(&t1, NULL, sendSock, (void *)&sock);
    pthread_t t2;
    pthread_create(&t2, NULL, recvSock, (void *)&sock);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    WSACleanup();

    return 0;
}

// gcc 14.news_sr_mul_win.c -o 14.news_sr_mul_win -lws2_32 && ./14.news_sr_mul_win

广播

14.news_sender_brd_win.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define IP "255.255.255.255"
#define PORT 9999
#define BUF_SIZE 30

void ErrorHanding(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    SOCKET hSendSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (hSendSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    int opt = 1;
    if (setsockopt(hSendSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0)
        ErrorHanding("setsockopt() error!");

    int so_brd = 1;
    if (setsockopt(hSendSock, SOL_SOCKET, SO_BROADCAST, (void *)&so_brd, sizeof(so_brd)) < 0)
        ErrorHanding("setsockopt() error!");

    int addr_size = sizeof(SOCKADDR);

    SOCKADDR_IN brdAdr;
    memset(&brdAdr, 0, addr_size);
    brdAdr.sin_family = AF_INET;
    brdAdr.sin_addr.s_addr = inet_addr(IP); // Broad IP
    brdAdr.sin_port = htons(PORT);          // Broad Port

    FILE *fp;
    if ((fp = fopen("14.news_sender_brd_win.c", "r")) == NULL)
        ErrorHanding("fopen() error!");

    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE - 1, fp);
        sendto(hSendSock, buf, strlen(buf), 0, (SOCKADDR *)&brdAdr, addr_size);
        Sleep(200);
    }
    fclose(fp);

    closesocket(hSendSock);

    WSACleanup();

    return 0;
}

// gcc 14.news_sender_brd_win.c -o 14.news_sender_brd_win -lws2_32 && ./14.news_sender_brd_win
14.news_receiver_brd_win.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define PORT 9999
#define BUF_SIZE 30

void ErrorHanding(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    SOCKET hRecvSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (hRecvSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    int opt = 1;
    if (setsockopt(hRecvSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0)
        ErrorHanding("setsockopt() error!");

    int addr_size = sizeof(SOCKADDR_IN);
    SOCKADDR_IN adr;
    memset(&adr, 0, addr_size);
    adr.sin_family = AF_INET;
    adr.sin_addr.s_addr = htonl(INADDR_ANY);
    adr.sin_port = htons(PORT);
    if (bind(hRecvSock, (struct sockaddr *)&adr, addr_size) == SOCKET_ERROR)
        ErrorHanding("bind() error!");

    while (1)
    {
        char buf[BUF_SIZE];
        int str_len = recvfrom(hRecvSock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    closesocket(hRecvSock);

    WSACleanup();

    return 0;
}

// gcc 14.news_receiver_brd_win.c -o 14.news_receiver_brd_win -lws2_32 && ./14.news_receiver_brd_win
14.news_sr_brd_win.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <pthread.h>
#include <unistd.h>

#define IP "255.255.255.255"
#define PORT 9999
#define BUF_SIZE 30

void ErrorHanding(const char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

void *sendSock(void *arg)
{
    SOCKET sock = *(SOCKET *)arg;

    int addr_size = sizeof(SOCKADDR_IN);

    SOCKADDR_IN brdAdr;
    memset(&brdAdr, 0, addr_size);
    brdAdr.sin_family = AF_INET;
    brdAdr.sin_addr.s_addr = inet_addr(IP); // Broad IP
    brdAdr.sin_port = htons(PORT);          // Broad Port

    /*
        if (connect(sock, (struct sockaddr *)&brdAdr, addr_size) == SOCKET_ERROR)
            ErrorHanding("connect() error");
    */

    sleep(1);

    FILE *fp;
    if ((fp = fopen("14.news_sender_brd_win.c", "r")) == NULL)
        ErrorHanding("fopen() error!");
    while (!feof(fp))
    {
        char buf[BUF_SIZE] = {0};
        fgets(buf, BUF_SIZE - 1, fp);
        sendto(sock, buf, strlen(buf), 0, (SOCKADDR *)&brdAdr, addr_size);
        // write(sock, buf, strlen(buf));
        Sleep(200);
    }
    fclose(fp);

    closesocket(sock);
    return NULL;
}

void *recvSock(void *arg)
{
    SOCKET sock = *(SOCKET *)arg;
    while (1)
    {
        char buf[BUF_SIZE] = {0};
        int str_len = recvfrom(sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        // int str_len = read(sock, buf, BUF_SIZE - 1);
        if (str_len <= 0)
            break;
        buf[str_len] = 0;
        fputs(buf, stdout);
    }
    return (void *)0;
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    int opt = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0)
        ErrorHanding("setsockopt() error!");

    int so_brd = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *)&so_brd, sizeof(so_brd)) < 0)
        ErrorHanding("setsockopt() error!");

    int addr_size = sizeof(SOCKADDR_IN);
    SOCKADDR_IN localAdr;
    memset(&localAdr, 0, addr_size);
    localAdr.sin_family = AF_INET;
    localAdr.sin_addr.s_addr = htonl(INADDR_ANY);
    localAdr.sin_port = htons(PORT);
    if (bind(sock, (struct sockaddr *)&localAdr, addr_size) == SOCKET_ERROR)
        ErrorHanding("bind() error!");

    pthread_t t1;
    pthread_create(&t1, NULL, sendSock, (void *)&sock);
    pthread_t t2;
    pthread_create(&t2, NULL, recvSock, (void *)&sock);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    WSACleanup();

    return 0;
}
// gcc 14.news_sr_brd_win.c -o 14.news_sr_brd_win -lws2_32 && ./14.news_sr_brd_win
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值