Linux C++ UDP通信 UDP广播 UDP多播

UDP客户端

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <time.h>
#include <string>

#define SERV_PORT 8000

char *randstr(char *str, const int len)
{
    srand(time(NULL));
    int i;
    for (i = 0; i < len; ++i)
    {
        switch ((rand() % 3))
        {
        case 1:
            str[i] = 'A' + rand() % 26;
            break;
        case 2:
            str[i] = 'a' + rand() % 26;
            break;
        default:
            str[i] = '0' + rand() % 10;
            break;
        }
    }
    str[++i] = '';
    return str;
}

int main(int argc, char *argv[])
{
    struct sockaddr_in servaddr;
    char buf[BUFSIZ];

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);

    while (true)
    {
        randstr(buf, 5);
        std::string str = "PID = ";
        str.append(std::to_string(getpid()));
        str.append(", ");
        str.append(buf);
        int n = sendto(sockfd, str.c_str(), str.size(), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
        if (n == -1)
        {
            perror("sendto error");
        }

        // NULL:不关心对端信息
        n = recvfrom(sockfd, buf, BUFSIZ, 0, NULL, 0);
        if (n == -1)
        {
            perror("recvfrom error");
        }
        printf("%s
", buf);
        sleep(rand() % 3 + 1);
    }

    close(sockfd);

    return 0;
}

UDP服务器

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ctype.h>

#define SERV_PORT 8000

int main(void)
{
    struct sockaddr_in serv_addr, clie_addr;
    char buf[BUFSIZ];
    char str[INET_ADDRSTRLEN];

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(SERV_PORT);

    bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    printf("Accepting connections ...
");
    while (true)
    {
        socklen_t clie_addr_len = sizeof(clie_addr);
        int n = recvfrom(sockfd, buf, BUFSIZ, 0, (struct sockaddr *)&clie_addr, &clie_addr_len);
        if (n == -1)
        {
            perror("recvfrom error");
        }

        printf("received from %s at PORT %d
", inet_ntop(AF_INET, &clie_addr.sin_addr, str, sizeof(str)), ntohs(clie_addr.sin_port));

        for (int i = 0; i < n; i++)
        {
            buf[i] = toupper(buf[i]);
        }

        n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&clie_addr, sizeof(clie_addr));
        if (n == -1)
        {
            perror("sendto error");
        }
        printf("%s
", buf);
    }
    close(sockfd);

    return 0;
}

UDP广播客户端

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERVER_PORT 8000
#define MAXLINE 4096
#define CLIENT_PORT 9000

int main(int argc, char *argv[])
{
    struct sockaddr_in localaddr;
    int confd;
    ssize_t len;
    char buf[MAXLINE];

    //1.创建一个socket
    confd = socket(AF_INET, SOCK_DGRAM, 0);

    //2.初始化本地端地址
    bzero(&localaddr, sizeof(localaddr));
    localaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "0.0.0.0" , &localaddr.sin_addr.s_addr);
    localaddr.sin_port = htons(CLIENT_PORT);

    int ret = bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr));  //显示绑定不能省略
    if (ret == 0)
    {
        printf("...bind ok...
");
    }

    while (true)
    {
        len = recvfrom(confd, buf, sizeof(buf), 0, NULL, 0);
        printf("%s
", buf);
    }
    close(confd);

    return 0;
}

UDP广播服务器

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>

// 无关紧要
#define SERVER_PORT 8000
#define MAXLINE 1500

#define BROADCAST_IP "192.168.80.255"
// 重要
#define CLIENT_PORT 9000

int main(void)
{
    int sockfd;
    struct sockaddr_in serveraddr, clientaddr;
    char buf[MAXLINE];

    /* 构造用于UDP通信的套接字 */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;                        /* IPv4 */
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);         /* 本地任意IP INADDR_ANY = 0 */
    serveraddr.sin_port = htons(SERVER_PORT);

    bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

    int flag = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));

    /*构造 client 地址 IP+端口  192.168.80.255+9000 */
    bzero(&clientaddr, sizeof(clientaddr));
    clientaddr.sin_family = AF_INET;
    inet_pton(AF_INET, BROADCAST_IP, &clientaddr.sin_addr.s_addr);
    clientaddr.sin_port = htons(CLIENT_PORT);

    int i = 0;
    while (true)
    {
        sprintf(buf, "Drink %d glasses of water
", i++);
        sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
        sleep(1);
    }
    close(sockfd);
    return 0;
}

UDP多播(组播)客户端

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>

#define SERVER_PORT 8000
#define CLIENT_PORT 9000

#define GROUP "239.0.0.2"

int main(int argc, char *argv[])
{
    struct sockaddr_in localaddr;
    int confd;
    ssize_t len;
    char buf[BUFSIZ];

    // 组播结构体
    struct ip_mreqn group;

    confd = socket(AF_INET, SOCK_DGRAM, 0);

    // 初始化
    bzero(&localaddr, sizeof(localaddr));
    localaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "0.0.0.0" , &localaddr.sin_addr.s_addr);
    localaddr.sin_port = htons(CLIENT_PORT);

    bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr));

    // 设置组地址
    inet_pton(AF_INET, GROUP, &group.imr_multiaddr);
    // 使用本地任意IP添加到组播组
    inet_pton(AF_INET, "0.0.0.0", &group.imr_address);
    // 通过网卡名-->编号 ip ad
    group.imr_ifindex = if_nametoindex("eth0");

    // 设置client 加入多播组
    setsockopt(confd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));

    while(true)
    {
        len = recvfrom(confd, buf, sizeof(buf), 0, NULL, 0);
        printf("%s
", buf);
    }
    close(confd);

    return 0;
}

UDP多播(组播)服务器

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>

#define SERVER_PORT 8000
#define CLIENT_PORT 9000
#define MAXLINE 1500

#define GROUP "239.0.0.2"

int main(void)
{
    int sockfd;
    struct sockaddr_in serveraddr, clientaddr;
    char buf[MAXLINE] = "itcast
";
    struct ip_mreqn group;

    // 构造用于UDP通信的套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&serveraddr, sizeof(serveraddr));
    // IPv4
    serveraddr.sin_family = AF_INET;
    // 本地任意IP INADDR_ANY = 0
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(SERVER_PORT);

    bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

    // 设置组地址
    inet_pton(AF_INET, GROUP, &group.imr_multiaddr);
    // 本地任意IP
    inet_pton(AF_INET, "0.0.0.0", &group.imr_address);
    // 给出网卡名,转换为对应编号: eth0 --> 编号  命令:ip ad
    group.imr_ifindex = if_nametoindex("eth0");
    printf("%d
", group.imr_ifindex);

    // 组播权限
    setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &group, sizeof(group));

    // 构造 client 地址 IP+端口
    bzero(&clientaddr, sizeof(clientaddr));
    clientaddr.sin_family = AF_INET;
    // IPv4  239.0.0.2+9000
    inet_pton(AF_INET, GROUP, &clientaddr.sin_addr.s_addr);
    clientaddr.sin_port = htons(CLIENT_PORT);

    int i = 0;
    while (true)
    {
        sprintf(buf, "LDC %d
", i++);
        sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
        sleep(1);
    }

    close(sockfd);

    return 0;
}
原文地址:https://www.cnblogs.com/duxie/p/15091621.html