gpt4 book ai didi

c - 在 MSG_DONTWAIT 模式下使用 recvfrom() 从原始套接字读取以太网数据包

转载 作者:太空狗 更新时间:2023-10-29 11:13:37 28 4
gpt4 key购买 nike

我使用原始套接字在 C 中使用 recvFrom() 发送和接收以太网数据包。我想以非阻塞模式阅读,所以我使用 MSG_DONTWAIT。但是 recvFrom() 总是返回 -1,无论是否接收到数据包。我是 C 编程的新手。我能够接收我的负载,但我总是收到消息“接收资源暂时不可用”。

代码片段:

    if ((sock = socket(AF_PACKET, SOCK_RAW, htons(0x8851))) < 0) { 
perror("ERROR: Socket");
exit(1);
}


while(1) {
int flag=0;
n=recvfrom(sock, buffer, 2048, MSG_DONTWAIT, NULL, NULL);

if (n == -1) {
perror("ERROR: Recvfrom");
close(sock);
flag=1;

}

if (flag==0) {
// Read Packet

}
}

最佳答案

如果为 recvfrom() 使用 MSG_DONTWAIT 参数,系统调用将始终立即返回是否有任何数据要读取。如果没有数据,则返回值为-1,然后将errno 设置为EAGAIN。在您的应用程序中,我不完全确定 MSG_DONTWAIT 是正确的选择。如果您唯一要做的就是从那个套接字读取数据包,则不应使用 MSG_DONTWAIT。因此,您的程序实际上会循环打印大量错误消息。如果您在 errno == EAGAIN 的情况下删除该错误消息,您的程序会稍微好一些,但不会好很多:它会陷入循环,消耗所有 CPU 资源。

但是,如果您同时读取多个文件描述符,那么使用非阻塞 I/O 是正确的选择。但是你应该有一个循环,而不是你的循环,使用 select()、poll() 或 epoll_wait() 来轮询多个文件描述符的准备情况。由于您在 Linux 上运行,我强烈推荐 epoll_wait() 因为它是这些方法中最具可扩展性的方法。有关详细信息,请参阅 Linux 上的 epoll、epoll_wait 和 epoll_create 手册页。

我强烈建议暂时不要使用 MSG_DONTWAIT 并检查函数调用是否返回。如果它永远不会返回,则意味着它没有收到任何数据包。

关于c - 在 MSG_DONTWAIT 模式下使用 recvfrom() 从原始套接字读取以太网数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29115729/

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