网络子系统75_套接字创建

简介:
//	创建套接字,系统调用sys_socket
//	步骤:
//		1.分配套接字描述符
//		2.创建套接字对应的文件描述符
//	参数:	
//			协议族:	对于TCP/IP协议族,该参数为AF_INET
//			套接字类型:流套接字类型为SOCK_STREAM, 数据报套接字类型为SOCK_DGRAM
//			通信协议:	单个协议系列中的不同传输协议,在internet通信域中,此参数一般取值为0,
//					  	系统根据套接字的类型决定应使用的传输层协议
1.1 SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
	int retval;
	struct socket *sock;
	int flags;

	....
	//创建套接字
	retval = sock_create(family, type, protocol, &sock);
	if (retval < 0)
		goto out;

	//创建套接字的文件描述符
	retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
	if (retval < 0)
		goto out_release;

out:
	//返回文件描述符
	return retval;

out_release:
	sock_release(sock);
	return retval;
}


//	创建套接字
//	步骤:
//		1.安全性检查
//		2.分配socket描述符
//		3.由具体协议执行进一步初始化
//	参数:	
//		kern,指示操作发起者所在层
2.1 int __sock_create(struct net *net, int family, int type, int protocol,
			 struct socket **res, int kern)
{
	int err;
	struct socket *sock;
	const struct net_proto_family *pf;

	//检查协议族
	if (family < 0 || family >= NPROTO)
		return -EAFNOSUPPORT;
	//检查套接字类型
	if (type < 0 || type >= SOCK_MAX)
		return -EINVAL;

	//兼容性检查,PF_INET中的SOCK_PACKET现在调整为PF_PACKET协议族
	if (family == PF_INET && type == SOCK_PACKET) {
		static int warned;
		if (!warned) {
			warned = 1;
			printk(KERN_INFO "%s uses obsolete (PF_INET,SOCK_PACKET)\n",
			       current->comm);
		}
		family = PF_PACKET;
	}

	//分配套接字内存
	sock = sock_alloc();

	//套接字类型
	sock->type = type;

	rcu_read_lock();
	pf = rcu_dereference(net_families[family]);
	rcu_read_unlock();

	//由具体的协议族执行进一步的初始化
	err = pf->create(net, sock, protocol, kern);
	if (err < 0)
		goto out_module_put;

	//返回创建好的套接字
	*res = sock;
	return 0;
}

//	分配socket描述符
//		socket描述符与inode节点相绑定,初始化inode操作集合
2.2 static struct socket *sock_alloc(void)
{
	struct inode *inode;
	struct socket *sock;

	//分配inode
	inode = new_inode_pseudo(sock_mnt->mnt_sb);
	if (!inode)
		return NULL;
	//inode与socket描述符同时分配,通过container_of返回socket描述符
	sock = SOCKET_I(inode);

	//inode号
	inode->i_ino = get_next_ino();
	//S_IFSOCK表示此inode为socket节点
	inode->i_mode = S_IFSOCK | S_IRWXUGO;
	inode->i_uid = current_fsuid();
	inode->i_gid = current_fsgid();
	//inode操作结合
	inode->i_op = &sockfs_inode_ops;
	//inode引用计数
	this_cpu_add(sockets_in_use, 1);
	return sock;
}

//	为套接字描述符分配文件描述符
3.1 static int sock_map_fd(struct socket *sock, int flags)
{
	//内核空间文件描述符
	struct file *newfile;
	//用户空间文件描述符
	int fd = get_unused_fd_flags(flags);
	if (unlikely(fd < 0))
		return fd;
	//分配文件描述符
	newfile = sock_alloc_file(sock, flags, NULL);
	if (likely(!IS_ERR(newfile))) {
		//向进程描述符安装文件描述符
		fd_install(fd, newfile);
		//返回用户空间描述符
		return fd;
	}
	put_unused_fd(fd);
	return PTR_ERR(newfile);
}

//	文件系统特定于进程的信息
4.1 struct task_struct
{
	...
	//所有打开文件的信息
	struct files_struct *files;
	...
}

4.2 struct files_struct {
  
  	atomic_t count;
	struct fdtable __rcu *fdt;
	struct fdtable fdtab;

	//下一个可用的文件描述符
	int next_fd;
	unsigned long close_on_exec_init[1];
	//比特位域,如果对应比特置位,则对应的文件描述符在使用中。
	unsigned long open_fds_init[1];
	//打开文件数组,NR_OPEN_DEFAULT=LONG_BITS
	struct file __rcu * fd_array[NR_OPEN_DEFAULT];
};

目录
相关文章
|
6月前
|
网络协议 安全 网络安全
Python网络编程详解:Socket套接字的使用与开发
探索Python网络编程:本文详述Socket套接字,关键组件用于设备间通信。理解Socket类型(TCP/UDP),学习创建、绑定、监听、发送/接收数据步骤。示例展示服务端和客户端实现,及Socket聊天室应用。了解并发处理、错误处理和网络安全。通过学习,提升网络应用开发技能。参考书籍深入学习。
174 2
|
6天前
|
Java
[Java]Socket套接字(网络编程入门)
本文介绍了基于Java Socket实现的一对一和多对多聊天模式。一对一模式通过Server和Client类实现简单的消息收发;多对多模式则通过Server类维护客户端集合,并使用多线程实现实时消息广播。文章旨在帮助读者理解Socket的基本原理和应用。
12 1
|
2月前
|
网络协议 算法 网络性能优化
C语言 网络编程(十五)套接字选项设置
`setsockopt()`函数用于设置套接字选项,如重复使用地址(`SO_REUSEADDR`)、端口(`SO_REUSEPORT`)及超时时间(`SO_RCVTIMEO`)。其参数包括套接字描述符、协议级别、选项名称、选项值及其长度。成功返回0,失败返回-1并设置`errno`。示例展示了如何创建TCP服务器并设置相关选项。配套的`getsockopt()`函数用于获取这些选项的值。
|
2月前
|
网络协议
关于套接字socket的网络通信。&聊天系统 聊天软件
关于套接字socket的网络通信。&聊天系统 聊天软件
|
3月前
|
网络协议 Java
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
这篇文章全面讲解了基于Socket的TCP网络编程,包括Socket基本概念、TCP编程步骤、客户端和服务端的通信过程,并通过具体代码示例展示了客户端与服务端之间的数据通信。同时,还提供了多个案例分析,如客户端发送信息给服务端、客户端发送文件给服务端以及服务端保存文件并返回确认信息给客户端的场景。
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
|
6月前
|
网络协议 算法 网络性能优化
网络编程:TCP/IP与套接字
网络编程:TCP/IP与套接字
|
6月前
|
网络协议 网络架构 Python
Python 网络编程基础:套接字(Sockets)入门与实践
【5月更文挑战第18天】Python网络编程中的套接字是程序间通信的基础,分为TCP和UDP。TCP套接字涉及创建服务器套接字、绑定地址和端口、监听、接受连接及数据交换。UDP套接字则无连接状态。示例展示了TCP服务器和客户端如何使用套接字通信。注意选择唯一地址和端口,处理异常以确保健壮性。学习套接字可为构建网络应用打下基础。
65 7
|
6月前
|
存储 网络协议 Java
[计算机网络]---网络编程套接字
[计算机网络]---网络编程套接字
|
5月前
|
网络协议 Java API
网络编程套接字(4)——Java套接字(TCP协议)
网络编程套接字(4)——Java套接字(TCP协议)
40 0
|
5月前
|
Java 程序员 Linux
网络编程套接字(3)——Java数据报套接字(UDP协议)
网络编程套接字(3)——Java数据报套接字(UDP协议)
45 0