linux 内核中accept实现

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 内核中accept实现相关的知识,希望对你有一定的参考价值。

目录

accept 系统调用

结构体之间的关系

inet_create

__fd_install


accept 系统调用

SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
		int __user *, upeer_addrlen, int, flags)

	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);

int __sys_accept4_file(struct file *file, unsigned file_flags,
		       struct sockaddr __user *upeer_sockaddr,
		       int __user *upeer_addrlen, int flags,
		       unsigned long nofile)

    //查找监听的sock
	sock = sock_from_file(file, &err);

    //申请并初始化新的socket
	newsock = sock_alloc();

	newsock->type = sock->type;
	newsock->ops = sock->ops;

    //新申请file,绑定到socket上
	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);

    //接收链接
	err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags,
					false);

    //添加新文件到当前进程的打开文件列表
	fd_install(newfd, newfile);
    ...

static const struct file_operations socket_file_ops = 
	.owner =	THIS_MODULE,
	.llseek =	no_llseek,
	.read_iter =	sock_read_iter,
	.write_iter =	sock_write_iter,
	.poll =		sock_poll,

;

static struct file *alloc_file(const struct path *path, int flags,
		const struct file_operations *fop)

	struct file *file;

	file->f_op = fop;
    
	return file;


struct file *alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt,
				const char *name, int flags,
				const struct file_operations *fops)


	file = alloc_file(&path, flags, fops);
    ...
	return file;



struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)

	struct file *file;

    //分配一个文件
	file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,
				O_RDWR | (flags & O_NONBLOCK),
				&socket_file_ops);
    
	sock->file = file;//绑定到socj->file上
	file->private_data = sock;//sock 又赋值到 file->private ?

	return file;

结构体之间的关系

  • struct file 结构体下的 *private_data 赋值为sock
  • accept⾥创建的新 socket ⾥的 file->f_op->poll 函数指向的是 sock_poll
  • sock->ops->accept 对应的⽅法是 inet_accept

inet_create

        在初始化过程中调用sock_init_data,主要sk_data_ready 设置了sock_def_readable在下文中会有调用。

void sock_init_data(struct socket *sock, struct sock *sk)

	sk->sk_state_change	=	sock_def_wakeup;
	sk->sk_data_ready	=	sock_def_readable;
	sk->sk_write_space	=	sock_def_write_space;
    ...

__fd_install

        添加新⽂件到当前进程的打开⽂件列表,file、socket、 sock 等内核对象创建完毕以后,它挂到当前进程的打开⽂件列表中。
void __fd_install(struct files_struct *files, unsigned int fd,
		struct file *file)


	fdt = files_fdtable(files);
	BUG_ON(fdt->fd[fd] != NULL);
	rcu_assign_pointer(fdt->fd[fd], file);



void fd_install(unsigned int fd, struct file *file)

	__fd_install(current->files, fd, file);


 


开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系

以上是关于linux 内核中accept实现的主要内容,如果未能解决你的问题,请参考以下文章

linux系统实现多个进程监听同一个端口

Linux系统优化实现高并发

Linux内核参数优化方案和设置步骤

TCP网络编程中connect()listen()和accept()三者之间的关系

linux内核参数优化-net

什么是节点?在linux内核中如何实现的?