Reputation: 575
I try to test zero copy networking on Ubuntu 20.04. I set the corresponding socket option and pass MSG_ZEROCOPY as parameter to the send call. Problem is that I never receive the response from the kernel. recvmsg is always EAGAIN. Is there something wrong how I setup the socket? Full server code can be found here. What I am doing is more or less this:
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
}
[Edit]
I realised that recvmsg actually returns but the counter is wrong. In my understanding each send increments the counter by 1. But after one send serr->ee_data is zero. After the second send serr->ee_data is 1. I certainly do misunderstand something here.
The fixed code is here.
Thanks!
Upvotes: 0
Views: 706
Reputation: 2211
From https://www.kernel.org/doc/html/v4.15/networking/msg_zerocopy.html :
Setting the socket option only works when the socket is in its initial (TCP_CLOSED) state
In your example, the socket is in the LISTEN state. So, i would suggest to try the following :
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);
Upvotes: 1