Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8130700
  • 博文数量: 159
  • 博客积分: 10424
  • 博客等级: 少将
  • 技术积分: 14615
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-14 12:45
个人简介

啦啦啦~~~

文章分类
文章存档

2015年(5)

2014年(1)

2013年(5)

2012年(10)

2011年(116)

2010年(22)

分类: LINUX

2011-01-11 23:55:34

内核中的UDP socket流程(6)——sendto
作者:gfree.wind@gmail.com

现在开始新的API sendto,那么就重新回到了socket.c文件。

SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
          unsigned, flags, struct sockaddr __user *, addr,
          int, addr_len)
{
     struct socket *sock;
     struct sockaddr_storage address;
     int err;
     struct msghdr msg;
     struct iovec iov;
     int fput_needed;

     sock = sockfd_lookup_light(fd, &err, &fput_needed);
     if (!sock)
          goto out;

通过函数sockfd_lookup_light和参数fd,来得到对应的sock。sockfd_lookup_light的实现比较简单,fd就是进程的fdtable的索引。通过这个fd索引就可以得到对应的file指针,然后在从file指针中,得到sock的地址。


     iov.iov_base = buff;
     iov.iov_len = len;
     msg.msg_name = NULL;
     msg.msg_iov = &iov;
     msg.msg_iovlen = 1;
     msg.msg_control = NULL;
     msg.msg_controllen = 0;
     msg.msg_namelen = 0;

初始化iov和msg,因为这里的消息传递方式采用的是4.4 BSD的消息传递方式。

struct msghdr {
     void * msg_name; /* Socket name */
     int msg_namelen; /* Length of name */
     struct iovec * msg_iov; /* Data blocks */
     __kernel_size_t msg_iovlen; /* Number of blocks */
     void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
     __kernel_size_t msg_controllen; /* Length of cmsg list */
     unsigned msg_flags;
};

通过查看msghdr结构体的定义,可以很容易的理解上述代码。


    if (addr) {
          err = move_addr_to_kernel(addr, addr_len, (struct sockaddr *)&address);
          if (err < 0)
               goto out_put;
          msg.msg_name = (struct sockaddr *)&address;
          msg.msg_namelen = addr_len;
     }
     if (sock->file->f_flags & O_NONBLOCK)
          flags |= MSG_DONTWAIT;
     msg.msg_flags = flags;

如果sendto指定了addr,那么首先将用户空间的地址addr复制到kernel空间的address中,并用内核空间的address来初始化msg;如果该socket指定了O_NONBLOCK,那么将flags设置上MSG_DONTWAIT,并将flags赋给msg.msg_flags。
err = sock_sendmsg(sock, &msg, len);
最后调用sock_sendmsg,将msg发送出去。

今天的sendto比较简单,就这么几行代码。明天学习sock_sendmsg。

阅读(9278) | 评论(5) | 转发(12) |
给主人留下些什么吧!~~

yang31413142012-11-27 15:39:57

GFree_Wind: 但是怎么会把一根网线就这样了呢。
你做了什么配置吗?如trunk等.....
这就是我不太懂的地方,组播通信,用的是UDP,当正常通信的时候,拔掉网线,数据发送不出去,这个时候下次来的数据应该覆盖上次的数据,是不是这样?  声明一下,这个程序不是我写的,我是负责系统移植和维护

GFree_Wind2012-11-27 13:55:22

yang3141314: 四个网卡不能正常发送数据! 我的理解是网络协议栈满了,阻塞了网络通信。.....
但是怎么会把一根网线就这样了呢。
你做了什么配置吗?如trunk等

yang31413142012-11-26 18:48:05

四个网卡不能正常发送数据! 我的理解是网络协议栈满了,阻塞了网络通信。

GFree_Wind2012-11-24 21:11:36

yang3141314: 哥们有个关于UDP的问题,想跟你探讨下!我做了一块板子,跑vxWorks5.5,板上一共四个网口,正常工作时候,四个网口分别对不同网段进行组播通信,这个时候如果拔.....
你说的不能工作,具体指什么?