gpt4 book ai didi

c - 如何正确使用 SO_RXQ_OVFL 检测 Linux 套接字上的 UDP 溢出?

转载 作者:太空狗 更新时间:2023-10-29 11:50:16 32 4
gpt4 key购买 nike

我想使用 Linux 套接字选项 SO_RXQ_OVFL 来检测 UDP 溢出。此选项使用辅助消息来报告丢弃的数据包数。来自男人:

SO_RXQ_OVFL (since Linux 2.6.33)
Indicates that an unsigned 32-bit value ancillary message (cmsg) should be
attached to received skbs indicating the number of packets dropped by the
socket between the last received packet and this received packet.

我的代码没有找到辅助消息。这是我所做的:

在启动时,我创建套接字并指定 SO_RXQ_OVFL 套接字选项:

int dropmonitor_on = 1;
if ( setsockopt(udpSocket, SOL_SOCKET, SO_RXQ_OVFL, &dropmonitor_on, sizeof(dropmonitor_on) ) != 0 )
{
perror("setsockopt SO_RXQ_OVFL not supported by your Linux Kernel");
}

然后我有一个调用 recvmsg 并查找辅助消息的接收函数:

struct sockaddr_in src_addr;  // The source address will be assigned to here

struct iovec iov[1];
iov[0].iov_base=ap_rxBuffer;
iov[0].iov_len=a_maxSizeBytes-1;

int cmsg_len = CMSG_SPACE(sizeof(uint32_t));
char cmsg[CMSG_SPACE(sizeof(uint32_t))];
memset(cmsg,0,cmsg_len);

struct msghdr message;
memset(&message,0,sizeof(struct msghdr));
message.msg_name=&src_addr;
message.msg_namelen=sizeof(struct sockaddr_in);
message.msg_iov=iov;
message.msg_iovlen=1;
message.msg_control=cmsg;
message.msg_controllen=cmsg_len;

int receivedBytes = 0;

if ( (receivedBytes = recvmsg( a_socket, &message, 0 )) == SOCKET_ERROR )
{
closeSocket(a_socket);
fatal("recvmsg() failed");
}
else
{
// Reception successful so interrogate ancillary message to get number of dropped packets

int udp_packets_dropped = 0;

struct cmsghdr* p_cmsg;
p_cmsg = CMSG_FIRSTHDR(&message);
for (p_cmsg = CMSG_FIRSTHDR(&message); p_cmsg != NULL; p_cmsg = CMSG_NXTHDR(&message, p_cmsg))
{
if ((p_cmsg->cmsg_level == SOL_SOCKET) && (p_cmsg->cmsg_type == SO_RXQ_OVFL))
{
int* p_udp_packets_dropped = (int *) CMSG_DATA(p_cmsg);
udp_packets_dropped = *p_udp_packets_dropped;
cout << "UDP pkts dropped: " << udp_packets_dropped << endl;
break;
}
}
if (p_cmsg == NULL)
{
fatal("Error: p_cmsg == NULL");
}
}

当我运行代码时,它因这个 fatal error 而停止:

Error: p_cmsg == NULL

由上面的代码生成,表示没有找到辅助消息。奇怪的是,有时我确实会收到一条辅助消息,所以也许我留下了一些未初始化的东西。

我仔细检查了代码,没有发现任何错误。请提供一些帮助,我将不胜感激。

最佳答案

我也有这个问题。

经过一番挖掘,我在内核源代码中发现了一些提示: https://github.com/torvalds/linux/blob/master/net/socket.c

static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
}

查看“if (... && SOCK_SKB_CB(skb)->dropcount)”,我认为如果dropcount为0,cmsg应该为空。您的代码应该是正确的。

关于c - 如何正确使用 SO_RXQ_OVFL 检测 Linux 套接字上的 UDP 溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40870873/

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