linux协议栈udp收发
刚学协议栈的同学可能不是找不见代码流程 而是不明白协议栈运行原理。例如进入内核态 中断 阻塞非阻塞等。
1 |
|
.
socket(AF_INET, SOCK_DGRAM, 0); -> inet_create
udp_rcv
__udp4_lib_rcv
udp_unicast_rcv_skb
udp_queue_rcv_skb
__udp_enqueue_schedule_skb
__skb_queue_tail
===================udp_queue_rcv_skb=========================
上面介绍了报文接收在软中断的处理流程,下面介绍用户态进程读取报文是如何实现的。用户态的recvmsg()最终会调用raw_recvmsg(),后者再调用skb_recv_datagram。如果套接字接收队列sk->sk_receive_queue中有报文就取skb并返回。否则调用wait_for_packet()等待,直到内核软中断收到报文并唤醒用户态进程。
sys_recvmsg()->sock_recvmsg()->…->sock_common_recvmsg()->raw_recvmsg()
sock_recvmsg
sock_recvmsg_nosec
sock->ops->recvmsg
inet_recvmsg //注册的ipv4 AF_INET
sk->sk_prot->recvmsg
udp_recvmsg //注册的数据包 SOCK_DGRAM
__skb_recv_udp
__skb_try_recv_from_queue //尝试从接收队列接收
__skb_wait_for_more_packets //如果不是非阻塞则 加入等待队列 休眠进程
1 |
|