网络编程常用接口的内核实现----sys_socket()

本文通过分析sys_socket()系统调用的源码,探讨了网络编程中创建套接字的过程,旨在帮助开发者更好地理解和运用网络协议栈,特别是在实现TCP连接迁移的内核模块开发中,这一理解至关重要。
摘要由CSDN通过智能技术生成

  最近在开发一个内核模块,主要的功能是在集群的节点之间迁移TCP连接,从而实现基于内容的调用。因此,花了很多时间和精力研究linux的网络协议栈,但是还是有很多地方没有串起来。网络协议栈是为用户层的应用开发服务的,因此决定从用户层常用的编程接口入手,通过学习这些接口的实现,来理清整个过程,加深对网络协议栈的理解。

  网络编程通常是基于客户端-服务端模型。首先启动服务器,稍后的某个时刻启动客户,它要连接到此服务器上。假设客户给服务器发送一个请求,服务器处理这个请求,并且给客户发送一个响应。为了执行网络I/O,第一件事情就是调用socket()函数来创建套接字。socket()函数对应的系统调用时sys_socket(),其源码及分析如下所示:

SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
	int retval;
	struct socket *sock;
	int flags;

	/* Check the SOCK_* constants for consistency.  */
	/*
	 * 下面的检查是在编译的时候进行的,如果这些
	 * 变量的值不一致,编译时会报错。
	 */
	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
	BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
	BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
	BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);

	/*
	 * 从linux 2.6.27开始,参数type除了指定套接字类型外,还
	 * 可以通过或运算来指定SOCK_CLOEXEC和SOCK_NONBLOCK标志
	 * 来改变套接字的行为。可以通过man socket命令查看详情。
	 * 首先通过SOCK_TYPE_MASK掩码来获取type中设置的标志(当然
	 * 也可能没有设置)。如果type中有标志设置,但是不是
	 * SOCK_CLOEXEC和SOCK_NONBLOCK对应的位,则返回EINVAL错误。
	 */
	flags = type & ~SOCK_TYPE_MASK;
	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
		return -EINVAL;
	/*
	 * 获取套接字类型
	 */
	type &= SOCK_TYPE_MASK;

	/*
	 * 如果SOCK_NONBLOCK不等于O_NONBLOCK并且设置了SOCK_NONBLOCK
	 * 标志,则将flags中的SOCK_NONBLOCK替换为O_NONBLOCK。
	 */
	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;

	/*
	 * 根据协议族类型和套接字类型创建套接字。
	 */
	retval = sock_create(family, type, protocol, &sock);
	if (retval < 0)
		goto out;

	/*
	 * 创建一个新的文件描述符,将新创建的
	 * socket实例关联上去。
	 */
	retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
	if (retval < 0)
		goto out_release;

out:
	/* It 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值