C++ Linux 创建UDP组播并发送数据

  • 步骤
    • 声明socket
    • 允许reuse socket
    • 支持设置TTL
    • 设置本机地址
    • 向内核申请加入一个组
    • [到此可以发数据等]
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <iostream>

using namespace std;

// 端口
int port = 12345;
// ttl
int ttl = 60;
// group
std::string group = "224.0.0.37";
// test str to be sent
std::string message = "hello world";

int main(int argc, char const *argv[])
{
    cout << "创建并加入组播组:group:" << group << ", port: " << port << ", TTL:" << ttl << endl;
    int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (udp_socket < 0)
    {
        perror("socket initilize failed");
        return 1;
    }
    // 允许reuse socket port
    u_int yes = 1;
    if (
        setsockopt(
            udp_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0)
    {
        perror("reuse addr failed");
        return 1;
    }

    // 设置TTL
    if (setsockopt(udp_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0)
    {
        perror("setsockopt ip_ttl failed");
        return 1;
    }
    // 设置本机地址
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);
    // bind socket
    if (bind(udp_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("bind socket error");
        return 1;
    }
    // 设置ip
    struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr(group.c_str());
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    
    if (setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
    {
        perror("set mutliaddr failed");
        return 1;
    }
    cout << "发送UDP组播,内容:" << message <<endl; 
    // 创建完成
    int nbytes = sendto(udp_socket, message.c_str(), message.size(), 0, (struct sockaddr *)&addr, sizeof(addr));
    if (nbytes < 0)
    {
        perror("send message failed");
    }
    else
    {
        cout << "发送成功";
    }
    return 0;
}

You may also like...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注