我正在使用原始套接字使用recvFrom()在C中发送和接收以太网数据包。我想在非阻塞模式下阅读,所以我使用的是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
}
}
答案 0 :(得分:2)
如果对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并检查函数调用是否会返回。如果它永远不会返回,则表示它没有收到任何数据包。