【问题标题】:Streaming on UDP在 UDP 上流式传输
【发布时间】:2011-09-05 12:48:41
【问题描述】:

我在这里遇到以下问题:我想在特定端口上的 UDP 套接字上编写服务器流数据,并且客户端应该能够连接到它并接收发送出去的数据,而不会有太多麻烦:他们只是连接,从一开始他们就应该使用recvfrom从服务器获取数据。

我在设置网络相关部分时遇到了一些问题。因此,这是我尝试编写的一段粗略代码:

int udpSock = socket(AF_INET, SOCK_DGRAM, 0);
if(udpSock == -1)
{
    perror("Could not create audio output socket");
    exit(1);
}

struct sockaddr_in *sin = (struct sockaddr_in*)&gOutgoingAddr;
sin->sin_port = htons(40200);
if(bind(udpSock, (const sockaddr*)sin, sizeof(struct sockaddr_in)) == -1)
{
    perror("Cannot bind audio socket");
    exit(1);
}

int buffer_size = 0;
char* data = get_next_buffer(&buffer_size);
while(buffer_size > 0)
{
    if(sendto(udpSock, (const void*)(data), buffer_size, 0, NULL, 0) == -1)
    {
        perror("sendto failure");
    }
    data = get_next_buffer(&buffer_size);
}

不用担心gOutgoingAddr变量,使用getifaddrs正确获取,有效。我对sendto 方法的参数化感到困扰,因为现在应用程序的输出是:

sendto failure: Destination address required

确实如此,因为我没有目标地址,因为到目前为止我发现的所有示例都显示了服务器何时获得客户端连接,并且有地址。但是由于我还没有连接客户端,所以我仍然想流式传输。

感谢所有帮助,我不知道应该为 sendto 的参数添加什么:

  1. gOutgoingAddress 是我创建套接字的地址?我已经尝试过了,但是如果我在指定端口上使用tcpdump linux 命令,我什么也得不到。
  2. 我应该创建一个多播套接字吗?这不知何故没有意义......
  3. 还有别的吗?

谢谢, frc

【问题讨论】:

    标签: c networking streaming udp posix


    【解决方案1】:

    您不能流到“无处”。通过 UDP 流式传输数据不是多播。这意味着如果您连接了 100 个客户端,则您必须将完全相同的数据发送 100 次,每次发送给将要接收它的每个客户端。多播并不是最初 IPv4 设计的一部分。它是后来添加的,并没有得到广泛的支持。这与 IPv6 不同,在 IPv6 中,多播已成为初始设计的一部分。你唯一能做的就是在你的本地网络中广播流量。这仅在所有客户端都在您的本地网段中时才有效。要广播您的服务器,只需将数据发送到 255.255.255.255 和固定的 UDP 端口。然后,所有客户端都必须侦听该特定端口并接收数据。请注意,在大多数系统上,您需要特殊权限才能进行广播(例如,仅允许以 root 权限运行的程序广播流量并不常见,因为广播会污染您的网络,因为所有广播数据包都会发送到网络中的所有客户端,不管他们是否关心他们)。没有广播,你只有单播,单播意味着一个发送者,一个接收者。对于一个发送方多个接收方,您必须将相同的数据多次发送到多个地址。

    【讨论】:

    • 许多(如果不是大多数)现代路由器都支持多播。可能是互联网服务提供商不支持它。例如,请参阅The BBC, Virgin Radio, EMAP and GCAP have begun delivering their Radio via Multicast
    • 我的回答中没有提到骨干互联网路由器。我指的是您在家庭和小型办公室网络中发现的典型设备,它们不支持 IPv4 多播,而且它也不支持第 2 层(以太网)多播,而是使用广播作为多播地址。
    【解决方案2】:

    顺便问一下,audioUdpSock 是什么? 你不应该改用 udpSock 吗?

    【讨论】:

    • 问题已编辑 :) audioUdpSock 是 udpSock,我只是修剪了原始来源以丢弃与问题无关的所有内容
    • 好的:) 我没明白这一点。您正在尝试流式传输,但您没有任何地址?或者您正在尝试在请求到来时流式传输到某个地址?
    • 我正在尝试流式传输,但我没有地址。我希望多个客户端能够连接到我的服务器并从它们连接的点开始接收数据。
    • 我明白了。我实际上不知道服务器做了什么,但 IGMP 窥探会为你做这件事。另一种方法是:您可以侦听客户端的套接字,然后获取地址并流向它
    【解决方案3】:

    在你的服务器上做一个recvfrom,并让客户端发送一条消息(你想要的任何内容,这只是建立连接的一种方式,一个问候)。然后服务端会得到来自recvfrom的客户端地址,并可以向它发送数据包。

    由于UDP套接字是无连接的(使用UDP套接字时不需要acceptconnect),你需要有另一种方式通知服务器客户端的存在(客户端需要有一种越界的方式来知道服务器地址,通常是用户提供的,或者是硬编码的)。

    如果您可以有多个客户端,那么您必须在套接字上使用 selectpoll... 以了解何时可以安全地调用 recvfrom 而不会阻塞(或者您可以配置您的套接字是非阻塞的)。

    编辑:我向大家强烈推荐Beej's Guide to Network Programming,对于你的问题,你可以直接去Datagram Socket的示例用法。

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 2022-12-16
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2013-06-01
      相关资源
      最近更新 更多