recv with flags MSG_DONTWAIT | TCP套接字上的MSG_PEEK

时间:2013-04-22 06:33:27

标签: linux sockets network-programming linux-kernel

我有一个用于交换消息的TCP流连接。这是在Linux内核中。使用者线程继续处理传入的消息。消费一条消息后,我想检查是否有更多待处理消息;在这种情况下,我也会处理它们。我的代码实现如下所示。 krecv是sock_recvmsg()的包装器,传递标志值而不进行修改(来自ksocket kernel模块的krecv)

使用MSG_DONTWAIT,我希望它不应该阻止,但显然它会阻塞。使用MSG_PEEK,如果没有要读取的数据,它应该只返回零。这种理解是否正确?有没有更好的方法来实现我在这里需要的东西?我猜这应该是一个常见的要求,因为经常使用跨节点传递的消息。

int recvd = 0;

do {
            recvd   += krecv(*sockp, (uchar*)msg + recvd, sizeof(my_msg) - recvd, 0); 
            printk("recvd = %d / %lu\n", recvd, sizeof(my_msg));
} while(recvd < sizeof(my_msg));
BUG_ON(recvd != sizeof(my_msg));

/* For some reason, below line _blocks_ even with no blocking flags */
recvd = krecv(*sockp, (uchar*)tempbuf, sizeof(tempbuf), MSG_PEEK | MSG_DONTWAIT);
if (recvd) {
            printk("more data waiting to be read");
            more_to_process = true;
} else {
            printk("NO more data waiting to be read");
}

2 个答案:

答案 0 :(得分:0)

您可以先检查缓冲区的长度:

int bytesAv = 0;
ioctl(m_Socket,FIONREAD,&bytesAv); //m_Socket is the socket client's fd 

如果其中有数据,则不应阻止带有MSG_PEEK的recv, 如果根本没有数据,则不需要MSG_PEEK, 这可能就是你想做的事。

答案 1 :(得分:0)

这是一个非常古老的问题,但是
1.问题存在
2.我面对它。

至少对我(Ubuntu 19.04和python 2.7)而言,此MSG_DONTWAIT无效,但是,如果我将超时设置为零(使用settimeout函数),则效果很好。
可以使用setockopt函数在c语言中完成此操作。