0

我有一个用于交换消息的 TCP 流连接。这是在 Linux 内核内部。消费者线程不断处理传入的消息。消费一条消息后,我想检查是否还有更多未决消息;在这种情况下,我也会处理它们。我实现这一点的代码如下所示。krecv 是 sock_recvmsg() 的包装器,无需修改即可传递标志值(来自ksocket 内核模块的 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");
}
4

2 回答 2

0

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

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

如果里面有数据,那么带有MSG_PEEK的recv不应该被阻塞,如果根本没有数据,那么不需要MSG_PEEK,这可能是你喜欢做的。

于 2016-08-31T01:22:07.380 回答
0

这是一个非常古老的问题,但是
1. 问题仍然存在
2. 我遇到了它。

至少对我来说(Ubuntu 19.04 和 python 2.7)这个 MSG_DONTWAIT 没有效果,但是如果我将超时设置为零(使用 settimeout 函数),它工作得很好。
这可以在 c 中使用 setsockopt 函数完成。

于 2020-03-30T05:32:16.350 回答