Linux内核--网络栈实现分析(七)--数据包的传递过程(下)

发表于:2012-12-29 10:14

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:闫明    来源:51Testing软件测试网采编

  注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析、”(下)“表示分析是从上向下分析。

  在博文Linux内核--网络栈实现分析(二)--数据包的传递过程(上)中分析了数据包从网卡设备经过驱动链路层,网络层,传输层到应用层的过程。

  本文就分析一下本机产生数据是如何通过传输层,网络层到达物理层的。

  综述来说,数据流程图如下:

  一、应用层

  应用层可以通过系统调用或文件操作来调用内核函数,BSD层的sock_write()函数会调用INET层的inet_wirte()函数。

/*
 * Write data to a socket. We verify that the user area ubuf..ubuf+size-1 is
 * readable by the user process.
 */

static int sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
{
 struct socket *sock;
 int err;
 
 if (!(sock = socki_lookup(inode)))
 {
  printk("NET: sock_write: can't find socket for inode!\n");
  return(-EBADF);
 }

 if (sock->flags & SO_ACCEPTCON)
  return(-EINVAL);
 
 if(size<0)
  return -EINVAL;
 if(size==0)
  return 0;
  
 if ((err=verify_area(VERIFY_READ,ubuf,size))<0)
    return err;
 return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
}

  INET层会调用具体传输层协议的write函数,该函数是通过调用本层的inet_send()函数实现功能的,inet_send()函数的UDP协议对应的函数为udp_write()

static int inet_send(struct socket *sock, void *ubuf, int size, int noblock,
        unsigned flags)
{
 struct sock *sk = (struct sock *) sock->data;
 if (sk->shutdown & SEND_SHUTDOWN)
 {
  send_sig(SIGPIPE, current, 1);
  return(-EPIPE);
 }
 if(sk->err)
  return inet_error(sk);
 /* We may need to bind the socket. */
 if(inet_autobind(sk)!=0)
  return(-EAGAIN);
 return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, flags));
}

static int inet_write(struct socket *sock, char *ubuf, int size, int noblock)
{
 return inet_send(sock,ubuf,size,noblock,0);
}

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号