从环回设备到网卡的多播

问题描述 投票:0回答:1

我正在尝试在同一主机中测试 UDP 多播。因为我只有 1 个网卡,我的想法是将多播数据发送到环回设备并在 NIC 上使用

谷歌搜索如何将多播数据发送到环回设备,我得到以下命令

ifconfig lo multicast
ip route add 239.0.0.2 dev lo
route add -net 224.0.0.0 netmask 240.0.0.0 dev lo
ifconfig lo multicast

以下是示例应用程序

发件人.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    const int delay_secs = 0;
    const char *message2 = "Hello, World!";

    unsigned long counter = 0;

    char message[8192] = {0};

    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
    {
        perror("socket(1)");
        return 1;
    }

    struct ip_mreq mreq;
    memset(&mreq, 0, sizeof(mreq));
    mreq.imr_interface.s_addr = inet_addr("127.0.0.1"); 

    if (
        setsockopt(
            fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&mreq, sizeof(mreq)) < 0)
    {
        perror("setsockopt(1)");
        return 1;
    }

    char loopch = 1;

        if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof(loopch)) < 0)
        {
        perror("setsockopt(2)");
        return 1;
    }

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("239.0.0.2");
    addr.sin_port = htons(1234);

    while (1)
    {
        char ch = 0;
        snprintf(message, 8192, "%s-%lu", message2, ++counter);
        int nbytes = sendto(
            fd,
            message,
            strlen(message),
            0,
            (struct sockaddr *)&addr,
            sizeof(addr));
        if (nbytes < 0)
        {
            perror("sendto");
            return 1;
        }
        sleep(delay_secs);
    }

    return 0;
}

listner.c


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define MSGBUFSIZE 8192

int main()
{
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
    {
        perror("socket");
        return 1;
    }

    u_int yes = 1;
    if (
        setsockopt(
            fd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
        return 1;
    }

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("239.0.0.2"); 
    addr.sin_port = htons(1234);

    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("bind");
        return 1;
    }

    struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr("239.0.0.2");
    mreq.imr_interface.s_addr = inet_addr("192.168.2.6"); //local wifi address
    if (
        setsockopt(
            fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
    {
        perror("setsockopt");
        return 1;
    }

    while (1)
    {
        char msgbuf[MSGBUFSIZE];
        int addrlen = sizeof(addr);
        int nbytes = recvfrom(
            fd,
            msgbuf,
            MSGBUFSIZE,
            0,
            (struct sockaddr *)&addr,
            &addrlen);
        if (nbytes < 0)
        {
            perror("recvfrom");
            return 1;
        }
        msgbuf[nbytes] = '\0';
        puts(msgbuf);
    }

    return 0;
}

这里到底出了什么问题。我正在尝试在运行 ubuntu 的个人设置中进行测试。

c linux udp multicast
1个回答
0
投票

msgbuf[nbytes] = '\0';
可能是缓冲区溢出。

也许:

  int nbytes = recvfrom(fd, msgbuf, 
    // MSGBUFSIZE,
    MSGBUFSIZE - 1,
    0, (struct sockaddr *)&addr, &addrlen);
© www.soinside.com 2019 - 2024. All rights reserved.