【发布时间】:2020-01-21 12:15:04
【问题描述】:
我无法从使用打开的多播套接字读取 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 标头和有效负载,我会得到整个
包。但是,如果我尝试先接收 RTP 标头,那么 - 自定义
有效载荷中的标头 - 第二个 read 总是获得下一个 RTP 标头,
丢弃所有附加数据。因为有效载荷长度可能会有所不同,所以唯一的方法是
接收一个完整的数据包,似乎是猜测它的最大可能大小。
我尝试在阅读之前获取一些可用字节:
ioctl(sock, FIONREAD, &nbytes);
但它总是返回 0。
对套接字的轮询总是失败,就好像根本没有数据可用。
启用非阻塞时(即fcntl(sock, F_SETFL, O_NONBLOCK);) - read
总是失败 (-1),recv(sock, buf, buf_len, MSG_DONTWAIT) 也是。
那么有没有办法通过相应的非阻塞来正确解析 RTP 数据包
read 来电?
非阻塞是必不可少的,因为应该可以检查连接是否丢失并在必要时重新打开套接字。
【问题讨论】:
标签: c sockets rtp multicastsocket