当前位置: 首页 > 知识库问答 >
问题:

C UDP 广播使用 ::write

苏彦君
2023-03-14

我正在编写一个UDP客户端/服务器应用程序。服务器是广播服务器,它通过特定端口向同一子网上的两个客户端广播。每个客户端接收一个数据报,并向服务器发送一个响应。每个客户端都预先知道服务器的ip地址。

我的客户端基本上与http://man7.org/linux/man-pages/man3/getaddrinfo.3.html,的客户端示例相同,即它使用connect()函数来指定所有传出数据包的endpoint。通过使用连接的UDP,客户端可以对套接字文件描述符使用read()和write(),而不是sendto/recvfrom。

对于我的服务器,我想采用类似的方法——配置套接字进行广播,并对文件描述符进行读/写调用。我可以绑定()套接字以侦听指定端口上的传入数据报,并且这些数据报收集得很好。

除去错误检查,我的服务器代码如下所示:

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

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

struct sockaddr_in servaddr;
memset((char*) &servaddr, 0, sizeof servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_port   = htons(PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

int success = bind(sockfd, (struct sockaddr*) &servaddr, sizeof servaddr);

int BUFSIZE = 256;
char buf[BUFSIZE];

while (1)
{
    // this works fine
    int bytes_read = read(sockfd, buf, BUFSIZE);

    // WANT TO BROADCAST HERE
    int bytes_written = write(sockfd, buf, bytes_read); 
}

但是,当我尝试在写()行广播数据包时,我得到了“未指定目标地址”错误。我可以调用连接()来设置目标地址,但我认为连接()在广播套接字上不起作用。

有没有办法使用 write() 而不是 sendto 进行广播?

共有1个答案

长孙沈义
2023-03-14

使用connect()进行广播的问题是(除了修改send()/write()的行为之外),connect()将在套接字上安装一个过滤器,以便它只接收源IP字段与connect的参数中指定的IP地址匹配的数据包。

这意味着,如果您在套接字上以广播地址作为参数调用connect(),那么套接字将只接收来自该广播地址的数据包——但数据包永远不会(AFAIK)标记为来自广播地址——相反,它们的“源IP”字段通常设置为发送数据包的计算机的IP地址。结果是,如果您将套接字连接到广播地址,则不会在该套接字上接收任何数据包。

 类似资料:
  • 输出如下: 如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。 较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。 如果满足以下规则,可以进行广播: 如果输入在每个维度中的大小与输出大小匹配,或其值正好为 1,则在计算中可它。 如果上述规则产生有效结果,并且满足以下条件之一,那么数组被称为可广播的。 数

  • 原文:Broadcasting 另见:numpy.broadcast 术语广播描述了NumPy在算术运算时如何处理不同形状的数组。 在某些条件下,较小的数组“广播”成较大的数组以便有相同的形状。 广播提供了一种矢量化操作数组的方法,这样可以在C而不是Python中进行循环。 它可以在不制作不必要的数据副本的情况下实现这一点,并且通常可以实现高效 然而,有些情况下广播是一个坏主意,因为它会导致内存使

  • 我在这里读了这个答案,也在这里读了这个答案,我正在努力找出最适合我的情况。 我在中启动一个服务,在这里我发出一个HTTP请求,并得到一个作为响应。然后我广播这个,并在我的活动中接收它。 问题是,用户显然可以通过打开抽屉并选择一个选项导航到另一个活动,而我可能会错过广播。 很明显,我可以让我的所有活动扩展一个抽象类,这个抽象类扩展了这里提到的,但我不能100%肯定这是最好的解决方案。如果用户在我收到

  • SocketIO另外一个非常有用的特性就是广播消息。Flask-SocketIO中,只要将broadcast = True这个可选参数加到send()和emit()中即可: @socketio.on('my event') def handle_my_custom_event(data): emit('my response', data, broadcast=True) 当一个消息以广播选

  • 我们所有的例子这一点利用传输方式称为“单播”:“将消息发送给一个网络拥有唯一地址的目的地”,这种模式支持连接和无连接协议。 然而,UDP 提供了额外的传输模式对多个接收者发送消息: 多播:传送给一组主机 广播:传送到网络上的所有主机(或子网) 示例应用程序在本章将说明使用 UDP 广播发送消息,可以接收到所有主机在同一网络。为此我们将使用特殊的“有限广播”或“零”网络地址255.255.255.2

  • 广播意味着向所有连接的客户端发送消息。 广播可以在多个级别完成。 我们可以将消息发送到所有连接的客户端,命名空间上的客户端和特定房间中的客户端。 要向所有客户端广播事件,我们可以使用io.sockets.emit方法。 Note - 这将向ALL连接的客户端发出事件(事件可能触发了此事件的套接字)。 在此示例中,我们将向所有用户广播已连接客户端的数量。 更新app.js文件以包含以下内容。 var