内核中的UDP socket流程(6)——sendto

简介: 内核中的UDP socket流程(6)——sendto作者:gfree.wind@gmail.com原文:http://blog.chinaunix.net/space.php?uid=23629988&do=blog&id=85912现在开始新的API sendto,那么就重新回到了socket.c文件。
内核中的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。

目录
相关文章
|
6月前
|
存储 Python
Python网络编程基础(Socket编程) UDP 发送和接收数据
【4月更文挑战第10天】对于UDP客户端而言,发送数据是一个相对简单的过程。首先,你需要构建一个要发送的数据报,这通常是一个字节串(bytes)。然后,你可以调用socket对象的`sendto`方法,将数据报发送到指定的服务器地址和端口。
|
6月前
|
网络协议 网络性能优化 开发者
Python网络编程基础(Socket编程)UDP Socket编程
【4月更文挑战第8天】Python网络编程中,UDP与TCP协议各有特点。TCP提供可靠连接,确保数据顺序与完整性,适合文件传输等;UDP则无连接,速度快,常用于实时音视频,牺牲了数据可靠性。Python的socket库支持两者,开发者可根据需求选择。
|
6月前
|
存储 Python
Python网络编程基础(Socket编程)UDP客户端编程
【4月更文挑战第9天】在UDP通信中,客户端负责发送数据到服务器,并接收来自服务器的响应。与服务器不同,客户端通常不需要绑定到特定的地址和端口,因为它可以临时使用任何可用的端口来发送数据。下面,我们将详细讲解UDP客户端编程的基本步骤。
|
6月前
|
网络协议 Python
Python网络编程基础(Socket编程)创建UDP socket对象
【4月更文挑战第8天】在Python中创建UDP服务器涉及使用`socket`模块创建socket对象,如`udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)`,然后绑定到特定IP地址和端口,如`udp_socket.bind(('localhost', 12345))`。服务器通过`recvfrom`在无限循环中监听和接收数据报。这只是基础,实际应用还需处理接收、解析、响应及错误处理等。接下来可学习如何利用socket对象进行数据交互以构建完整服务器。
|
1月前
|
存储 网络协议 Java
【网络】UDP回显服务器和客户端的构造,以及连接流程
【网络】UDP回显服务器和客户端的构造,以及连接流程
49 2
|
1月前
|
网络协议 Linux 网络性能优化
Linux基础-socket详解、TCP/UDP
综上所述,Linux下的Socket编程是网络通信的重要组成部分,通过灵活运用TCP和UDP协议,开发者能够构建出满足不同需求的网络应用程序。掌握这些基础知识,是进行更复杂网络编程任务的基石。
91 1
|
6月前
|
网络协议 Java
Java的Socket编程:TCP/IP与UDP深入探索
Java的Socket编程:TCP/IP与UDP深入探索
97 0
|
2月前
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。
|
2月前
|
网络协议 Linux
TCP 和 UDP 的 Socket 调用
【9月更文挑战第6天】
|
4月前
|
Java 数据格式
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
82 0