Raw Socket中recv系列调用与网卡缓冲区相关问题咨询
Raw Socket相关问题解答
问题1:调用recv()、recvfrom()、recvmsg()是否本质是将数据从网卡缓冲区复制到主内存缓冲区?
不是直接从网卡缓冲区复制到用户空间的主内存缓冲区,实际流程是分层的:
- 网卡收到数据后,先暂存在自身的硬件缓冲区(比如你提到的环形缓冲区);
- 接着通过DMA(直接内存访问)将数据从网卡硬件缓冲区复制到内核的套接字缓冲区(skb),这个过程不需要CPU参与;
- 当你调用
recv()/recvfrom()/recvmsg()时,是把数据从内核的套接字缓冲区复制到你指定的用户空间主内存缓冲区里。
简单说,这些接口完成的是内核缓冲区到用户缓冲区的复制,而非直接从网卡硬件缓冲区读取。
问题2:假设网卡采用环形缓冲区设计,大小为3000字节,已接收两个1500字节的数据包,调用recvfrom()或recvmsg()时是否会移动环形缓冲区的读指针?
不会。网卡环形缓冲区的读指针移动时机是在数据被DMA到内核缓冲区之后,和用户调用recvfrom()/recvmsg()无关:
- 当网卡收到第一个1500字节的包,DMA完成后,网卡的读指针会向后移动1500字节;
- 收到第二个1500字节的包后,DMA完成,读指针会再移动1500字节,刚好回到环形缓冲区的起始位置(因为总大小3000字节);
- 你调用
recvfrom()/recvmsg()时,操作的是内核里已经缓存好的数据,只会影响内核套接字缓冲区的相关指针,完全不会触动网卡硬件环形缓冲区的读指针。
内容的提问来源于stack exchange,提问作者Akbar294
相关产品推荐
相关产品推荐

