加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[十二]:UDP模块 - 收发

发布时间:2016-09-26 03:21:42 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核版本:2.6.34 UDP报文接收 UDP报文的接收可以分为两个部分:协议栈收到udp报文,插入相应队列中;用户 调用recvfrom()或recv()系统调用从队列中取出报文,这里的队列就是sk-sk_receive_queue,它是报文中转的纽带,两部 分的联系如下图所示。

第二部分:用户如何收取报文

用户可以调用sys_recvfrom()或sys_recv()来接收报文,所不同的是 ,sys_recvfrom()可能通过参数获得报文的来源地址,而sys_recv()则不可以,但对接收报文并没有影响。在用户调用 recvfrom()或recv()接收报文前,发给该socket的报文都会被添加到sk->sk_receive_queue上,recvfrom()和recv()要做的 就是从sk_receive_queue上取出报文,拷贝到用户空间,供用户使用。

sys_recv() -> sys_recvfrom()

sys_recvfrom () -> sk->ops->recvmsg()

==> sock_common_recvmsg() -> sk->sk_prot->recvmsg()

==> udp_recvmsg()

sys_recvfrom()

调用sock_recvmsg()接收udp报文,存放在msg中,如果接收到报文,从内核到用户空 间拷贝报文的源地址到addr中,addr是recvfrom()调用的传入参数,表示报文源的地址。而报文的内容是在udp_recvmsg()中从 内核拷贝到用户空间的。

err = sock_recvmsg(sock, &msg, size, flags);     
if (err >= 0 && addr != NULL) {     
 err2 = move_addr_to_user((struct sockaddr *)&address,     
    msg.msg_namelen, addr, addr_len);     
 if (err2 < 0)     
  err = err2;     
}

udp_recvmsg() 接收udp报文

这个函数有三个关键操作:

1. 取到数据包 -- __skb_recv_datagram()

2. 拷贝数据 -- skb_copy_datagram_iovec()或skb_copy_and csum_datagram_iovec()

3. 必要时计算校 验和 – skb_copy_and_csum_datagram_iovec()

Linux内核分析 - 网络[十二]:UDP模块 - 收发

__skb_recv_datagram(),它会从sk->sk_receive_queue上取出一个skb,前面已经分析到,内核收到发往该socket 的报文会放在sk->sk_receive_queue。

skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), &peeked, &err);

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读