【发布时间】:2010-09-25 03:27:40
【问题描述】:
如何在 Linux 中使用 C 进行 UDP 广播?
【问题讨论】:
-
以编程方式,还是通过实用程序/工具?
如何在 Linux 中使用 C 进行 UDP 广播?
【问题讨论】:
通常使用伯克利套接字 API,将 sendto() 一个或多个数据报发送到已知的 broadcast-class IP 地址。
【讨论】:
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");
}
【讨论】:
我最近写了 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);
}
}
【讨论】:
在许多 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. */
【讨论】:
sendto() shall fail if the SO_BROADCAST option is not set for the socket
this code does not work 的意思吗?该问题不包含任何代码。
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。这里的措辞只是让这个答案有点难以理解。