如何在 Linux 中使用 C 进行 UDP 广播?

Posted

技术标签:

【中文标题】如何在 Linux 中使用 C 进行 UDP 广播?【英文标题】:How to UDP Broadcast with C in Linux? 【发布时间】:2010-09-25 03:27:40 【问题描述】:

【问题讨论】:

以编程方式,还是通过实用程序/工具? 【参考方案1】:

通常使用伯克利套接字 API,将 sendto() 一个或多个数据报发送到已知的 broadcast-class IP 地址。

【讨论】:

我更改了建议的函数,以匹配 shodane 挖出的实际代码。【参考方案2】:

Unwind 是对的,除非你应该使用 'sendto'

这是一个示例,假设您已经有一个套接字。取自clamav

static void
broadcast(const char *mess)

    struct sockaddr_in s;

    if(broadcastSock < 0)
        return;

    memset(&s, '\0', sizeof(struct sockaddr_in));
    s.sin_family = AF_INET;
    s.sin_port = (in_port_t)htons(tcpSocket ? tcpSocket : 3310);
    s.sin_addr.s_addr = htonl(INADDR_BROADCAST);

    cli_dbgmsg("broadcast %s to %d\n", mess, broadcastSock);
    if(sendto(broadcastSock, mess, strlen(mess), 0, (struct sockaddr *)&s, sizeof(struct sockaddr_in)) < 0)
        perror("sendto");

【讨论】:

请更正源链接以使其有效和html锚元素。【参考方案3】:

我最近写了 udp 组播服务器进行测试。要订阅多播,您需要为客户端订阅多播组 225.0.0.37 端口 12346 和端口 12345(2 个提要 - 一个提要发送“Hello,World!”另一个“Bye,Office!”)。

我一直在用它来测试我的客户端,客户端和服务器都在同一个盒子上运行,所以可能有些位可能不起作用,但请先尝试一下。

#include <stdlib.h>
#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 <unistd.h>


#define BYE_OFFICE 12346
#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"

int main(int argc, char *argv[])

    struct sockaddr_in addr;
    struct sockaddr_in addr2;
    int fd;
    int fd2;
    char *message = "Hello, World!";
    char *message2 = "Bye, Office!";

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    
        perror("socket");
        exit(1);
    

    if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    
        perror("socket");
        exit(1);
    

    /* set up destination address */
    memset(&addr,0,sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(HELLO_GROUP);
    addr.sin_port=htons(HELLO_PORT);

    memset(&addr2,0,sizeof(addr2));
    addr2.sin_family = AF_INET;
    addr2.sin_addr.s_addr = inet_addr(HELLO_GROUP);
    addr2.sin_port=htons(BYE_OFFICE);

    while (1)
    
        if (sendto(fd, message, strlen(message), 0,(struct sockaddr *) &addr, sizeof(addr)) < 0)
        
            perror("sendto");
            exit(1);
        
        sleep(3);
        if (sendto(fd2, message2, strlen(message2), 0,(struct sockaddr *) &addr2, sizeof(addr2)) < 0)
        
            perror("sendto2");
            exit(1);
        
        sleep(3);
    

【讨论】:

这与问题有什么关系?问题是关于广播的,这是关于多播的 讨厌唤醒死线程,但 IMO 这与问题有关,只是可能有点冗长。在我看来,这是此页面上更有用的答案——除了提到您的套接字需要广播权限的答案。虽然多播和广播不同,但此代码在功能上与广播相同。【参考方案4】:

在许多 IP 堆栈中,例如 Linux,此代码不起作用。您的套接字必须具有广播权限。试试这个:

bcast_sock = socket(AF_INET, SOCK_DGRAM, 0);
int broadcastEnable=1;
int ret=setsockopt(bcast_sock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));

/* Add other code, sockaddr, sendto() etc. */

【讨论】:

是对的!如果您不授予套接字广播权限,您将收到权限被拒绝错误消息。 POSIX实际上需要这种行为,见pubs.opengroup.org/onlinepubs/009695399/functions/sendto.htmlsendto() shall fail if the SO_BROADCAST option is not set for the socket 您能澄清一下this code does not work 的意思吗?该问题不包含任何代码。 @EmilS。看看其他答案。他们都是 08 年的,而这个是 12 年的。我已经有没有setsockopt 的代码,但它不起作用。所以这就是为什么。我投赞成票。 是的,这个答案中的代码示例确实很好地回答了这个问题并且使用了最新的代码。但是我还是不知道this code does not work引用了哪个代码。如果引用其他答案中的代码,则应为The code from the other answers does not work。如果提到具体答案,可以使用The code from [user]'s answer does not work 甚至does not work by itself。这里的措辞只是让这个答案有点难以理解。

以上是关于如何在 Linux 中使用 C 进行 UDP 广播?的主要内容,如果未能解决你的问题,请参考以下文章

Linux 上 C 中的 UDP 发送方和 Windows 上 Qt 中的接收方不起作用? [关闭]

如何使用UDP进行跨网段广播

使用 ::write 的 C++ UDP 广播

如何在 UDP 广播中处理同时作为发送方和接收方的客户端

如何通过 UDP 套接字进行广播?

使用UDP广播检测网络上的多个设备-C#