gpt4 book ai didi

无法通过多个 'read' 调用从多播套接字读取 RTP 数据包(或获取其大小)

转载 作者:行者123 更新时间:2023-11-30 14:32:22 24 4
gpt4 key购买 nike

我在从使用打开的多播套接字读取 RTP 数据包时遇到问题以下功能:

int
open_multicast_socket
(const char *group_address,
uint16_t port)
{
assert(group_address != NULL);

int
s;

if (-1 != (s = socket(
AF_INET, SOCK_DGRAM, 0
)))
{
int
reuse = 1;

if (-1 != setsockopt(
s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse
))
{
struct sockaddr_in
sock_addr;

bzero(&sock_addr, sizeof sock_addr);

if (1 == inet_pton(
AF_INET, group_address, &sock_addr.sin_addr
))
{
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(port);

if (0 == bind(
s, (struct sockaddr*)&sock_addr, sizeof sock_addr
))
{
struct ip_mreq
mreq = {
.imr_multiaddr.s_addr = inet_addr(group_address),
.imr_interface.s_addr = htonl(INADDR_ANY)
};

if (0 == setsockopt(
s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof mreq
))
{
//fcntl(s, F_SETFL, O_NONBLOCK);
return s;
} // setsockopt
else
{
perror("setsockopt");
close(s);
}
} // bind
else
{
perror("bind");
close(s);
}
} // inet_pton
else
{
perror("inet_pton");
close(s);
}
} // setsockopt
else
{
perror("setsockopt");
close(s);
}
} // socket
else
{
perror("socket");
}

return -1;
}

如果我在一个read操作中读取RTP header 和有效负载,我会得到整个包。但是,如果我尝试先接收 RTP header ,那么 - 自定义有效负载中的 header - 第二次读取总是获取下一个 RTP header ,丢弃所有附加数据。由于有效负载长度可能会有所不同,因此唯一的方法是接收一个完整的数据包,看起来就是猜测它的最大可能大小。

在读取之前我尝试获取一些可用字节:

ioctl(sock, FIONREAD, &nbytes);

但它总是返回 0。

对套接字的轮询总是失败,就好像根本没有可用数据一样。

当启用非阻塞时(即fcntl(sock, F_SETFL, O_NONBLOCK);) - 读取总是失败 (-1),recv(sock, buf, buf_len, MSG_DONTWAIT) 也是如此。

有没有一种方法可以通过连续的非阻塞来正确解析 RTP 数据包读取调用?

非阻塞至关重要,因为应该可以检查连接是否丢失并在必要时重新打开套接字。

最佳答案

与基于流的协议(protocol) TCP 不同,UDP 是基于数据包的协议(protocol)。这意味着每当您从 UDP 套接字(无论是否多播)读取数据时,您都会得到一个 UDP 数据报。如果缓冲区不够大,无法容纳整个数据报,则剩余数据基本上会丢失。

确保您的缓冲区足够大以容纳完整的数据报。如果您的网络支持端到端巨型帧,则意味着您的缓冲区应为 9000 字节,否则应为 1500 字节。

关于无法通过多个 'read' 调用从多播套接字读取 RTP 数据包(或获取其大小),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59840946/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com