我尝试在Ubuntu 20.04上测试零复制网络。我设置了相应的套接字选项,并将MSG_ZEROCOPY作为参数传递给send调用。问题是我从来没有收到内核的响应。recvmsg总是EAGAIN。我设置插座的方式是否有问题?完整的服务器代码可以在这里找到。我所做的差不多是这样的:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bind(sockfd, (SA*)&servaddr, sizeof(servaddr);
listen(sockfd, 5);
setsockopt(sockfd, SOL_SOCKET, SO_ZEROCOPY, &optValue, sizeof(one));
connfd = accept(sockfd, (SA*)&cli, &len);
send(connfd, buff, MAX, MSG_DONTWAIT | MSG_ZEROCOPY)
ret = recvmsg(sockfd, &msg, MSG_ERRQUEUE);
if (ret == -1 && errno == EAGAIN)
{
// it's always here
}
[编辑]
我意识到recvmsg实际上返回,但计数器是错误的。在我的理解中,每次发送都会使计数器增加1。但是在一次发送之后,server ->ee_data为零。在第二次发送后,server ->ee_data为1。我肯定有些地方误解了。
固定代码在这里。
谢谢!
From https://www.kernel.org/doc/html/v4.15/networking/msg_zerocopy.html:
设置套接字选项仅在套接字初始化时有效(tcp_close)状态
在您的示例中,套接字处于LISTEN状态。因此,我建议尝试以下操作:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
/* try to set the option before listen is called */
if (setsockopt(sockfd, SOL_SOCKET, SO_ZEROCOPY, &optValue, sizeof(one)))
perror("setsocketopt");
bind(sockfd, (SA*)&servaddr, sizeof(servaddr);
listen(sockfd, 5);