linux 内核中accept实现
Posted 为了维护世界和平_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 内核中accept实现相关的知识,希望对你有一定的参考价值。
目录
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实现的主要内容,如果未能解决你的问题,请参考以下文章