内核中的UDP socket流程(1)

简介: 内核中的UDP socket流程(1)作者:gfree.wind@gmail.com原文:http://blog.chinaunix.net/u3/116859/showart.php?id=2443229相对于TCP,UDP协议要简单的多。

内核中的UDP socket流程(1)

作者:gfree.wind@gmail.com

相对于TCP,UDP协议要简单的多。所以我决定由简入繁,先从UDP协议入手。

前一遍文章已经确定了struct sk_buff被用于socket的接受和发送缓冲。那么为了摸清linux发送数据的流程,我们就可以顺着socket中的变量sk_write_queue来从最上层的发送函数开始,一直追溯到最底层。

在追溯的过程中,我一直向上遍历到socket层。那么就从UDP socket开始进行从上到下的展示。

socket的主要处理函数都在linux/net/socket.c的文件中。

对于UDP socket来说,用户空间涉及到的API,一般常用的是socket,sendto,recvfrom,close。当然,如果还有同样是用于发送的write,send,用于接受的read,recv等等,但都大同小异。

所以,这里只研究socket,send,recv和close

Linux中的API都是使用宏SYSCALL_DEFINEx作为前缀的,其中x是该API的参数的个数。在此我并不研究这个宏是如何实现的,因为那个不是TCP/IP的重点。————有兴趣的朋友可以自己去看该宏的定义。SYSCALL_DEFINE位于linux/include/linux/syscalls.h中。
这里我们只需要记住,其中的x是API参数的个数,而该宏的第一个参数,就是API的名字——这样我们就可以很方便的找到用户空间API对应的Linux内核中的代码了。

1. 这个是API socket的定义

SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)


2. 这个是API sendto的定义

SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,

unsigned, flags, struct sockaddr __user *, addr,

int, addr_len)


3. 这个是API recvfrom的定义

SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t size,
        unsigned, flags, struct sockaddr __user *, addr,
        int __user *, addr_len)



第4个API close与前面三个API不同。对于用户空间的程序来说, socket返回的值同样是被当做文件描述符fd的————对于Linux来说,这是linux的一大特征,用虚拟文件层去封装底层的复杂性。无论是设备,还是socket,都可以看做文件,而在代码实现上也是如此。因为我对VFS并不熟悉,只知道大概原理,所以再细的东西我也不清楚,以后可以研究一下。

那么对于socket来说,必然有一套符合文件操作的接口。请看下面的代码

static const struct file_operations socket_file_ops = {
    .owner =    THIS_MODULE,
    .llseek =    no_llseek,
    .aio_read =    sock_aio_read,
    .aio_write =    sock_aio_write,
    .poll =        sock_poll,
    .unlocked_ioctl = sock_ioctl,
#ifdef CONFIG_COMPAT
    .compat_ioctl = compat_sock_ioctl,
#endif
    .mmap =        sock_mmap,
    .open =        sock_no_open,    /* special open code to disallow open via /proc */
    .release =    sock_close,
    .fasync =    sock_fasync,
    .sendpage =    sock_sendpage,
    .splice_write = generic_splice_sendpage,
    .splice_read =    sock_splice_read,
};

看到这里,我们都不需要去查看struct file_operations的定义,就可以判断出socket的close动作必然是调用了sock_close。
那么 
4. 这个就是API close(对于socket)的定义

static int sock_close(struct inode *inode, struct file *filp)


好,明天再继续看具体的API

相关文章
|
4月前
|
存储 Python
Python网络编程基础(Socket编程) UDP 发送和接收数据
【4月更文挑战第10天】对于UDP客户端而言,发送数据是一个相对简单的过程。首先,你需要构建一个要发送的数据报,这通常是一个字节串(bytes)。然后,你可以调用socket对象的`sendto`方法,将数据报发送到指定的服务器地址和端口。
|
4月前
|
网络协议 网络性能优化 开发者
Python网络编程基础(Socket编程)UDP Socket编程
【4月更文挑战第8天】Python网络编程中,UDP与TCP协议各有特点。TCP提供可靠连接,确保数据顺序与完整性,适合文件传输等;UDP则无连接,速度快,常用于实时音视频,牺牲了数据可靠性。Python的socket库支持两者,开发者可根据需求选择。
|
4月前
|
存储 Python
Python网络编程基础(Socket编程)UDP客户端编程
【4月更文挑战第9天】在UDP通信中,客户端负责发送数据到服务器,并接收来自服务器的响应。与服务器不同,客户端通常不需要绑定到特定的地址和端口,因为它可以临时使用任何可用的端口来发送数据。下面,我们将详细讲解UDP客户端编程的基本步骤。
|
4月前
|
网络协议 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对象进行数据交互以构建完整服务器。
|
4月前
|
网络协议 Java
Java的Socket编程:TCP/IP与UDP深入探索
Java的Socket编程:TCP/IP与UDP深入探索
65 0
|
14天前
|
网络协议 Linux
TCP 和 UDP 的 Socket 调用
【9月更文挑战第6天】
|
2月前
|
Java 数据格式
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
37 0
|
3月前
|
存储 网络协议 数据处理
【Socket】解决UDP丢包问题
UDP(用户数据报协议)是一种无连接的传输层协议,因其不保证数据包的顺序到达和不具备内置重传机制,导致在网络拥塞、接收缓冲区溢出或发送频率过快等情况下容易出现丢包现象。为应对这些问题,可以在应用层实现重传机制、使用前向纠错码等方法。这些方法在一定程度上可以缓解UDP通信中的丢包问题,提高数据传输的可靠性和效率。
|
3月前
|
网络协议 应用服务中间件 网络性能优化
解析TCP /UDP协议的 socket 调用的过程
【6月更文挑战第2天】该文介绍了传输层的两种主要协议TCP和UDP的区别。TCP是面向连接、可靠的,提供顺序无错的数据传输,而UDP则是无连接、不可靠的,不保证数据顺序或不丢失。
|
4月前
|
算法 Linux 调度
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
347 1
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程