accept系统调用完成的工作是,从已经完成三次握手的连接队列中取一个连接,进行后续服务;

调用过程中,会重新分配一个socket,以及关联文件和传输控制块,如果应用层需要获取对端信息,则将对端信息拷贝到用户空间;

 /*
* For accept, we attempt to create a new socket, set up the link
* with the client, wake up the client, then return the new
* connected fd. We collect the address of the connector in kernel
* space and move it to user at the very end. This is unclean because
* we open the socket then return an error.
*
* 1003.1g adds the ability to recvmsg() to query connection pending
* status to recvmsg. We need to add that support in a way thats
* clean when we restucture accept also.
*/ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
int __user *, upeer_addrlen, int, flags)
{
struct socket *sock, *newsock;
struct file *newfile;
int err, len, newfd, fput_needed;
struct sockaddr_storage address; /* 只支持cloexec和nonblock */
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
return -EINVAL; /* 如果阻塞标记不等&& 有阻塞标记,则替换为O_NONBLOCK */
if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; /* 找到socket */
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (!sock)
goto out; err = -ENFILE; /* 分配一个新socket */
newsock = sock_alloc();
if (!newsock)
goto out_put; /* 类型和操作与本端socket相同 */
newsock->type = sock->type;
newsock->ops = sock->ops; /*
* We don't need try_module_get here, as the listening socket (sock)
* has the protocol module (sock->ops->owner) held.
*/
/* 增加模块引用 */
__module_get(newsock->ops->owner); /* 获取新的文件描述符 */
newfd = get_unused_fd_flags(flags);
if (unlikely(newfd < )) {
err = newfd;
sock_release(newsock);
goto out_put;
} /* 分配新的文件 */
newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
if (IS_ERR(newfile)) {
err = PTR_ERR(newfile);
put_unused_fd(newfd);
sock_release(newsock);
goto out_put;
} /* accept检查 */
err = security_socket_accept(sock, newsock);
if (err)
goto out_fd; /* 执行具体的accept操作 */
err = sock->ops->accept(sock, newsock, sock->file->f_flags, false);
if (err < )
goto out_fd; /* 指定了获取对端信息 */
if (upeer_sockaddr) {
if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
&len, ) < ) {
err = -ECONNABORTED;
goto out_fd;
} /* 拷贝对端地址到用户空间结构 */
err = move_addr_to_user(&address,
len, upeer_sockaddr, upeer_addrlen);
if (err < )
goto out_fd;
} /* File flags are not inherited via accept() unlike another OSes. */ /* 绑定描述符和文件 */
fd_install(newfd, newfile);
err = newfd; out_put:
fput_light(sock->file, fput_needed);
out:
return err;
out_fd:
fput(newfile);
put_unused_fd(newfd);
goto out_put;
} SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
int __user *, upeer_addrlen)
{
return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, );
}

inet_accept函数调用传输层的accept操作,并且返回新的连接控制块,新的连接控制块需要与新的socket进行关联,accept完成,将新socket的状态设置为已连接状态;

 /*
* Accept a pending connection. The TCP layer now gives BSD semantics.
*/ int inet_accept(struct socket *sock, struct socket *newsock, int flags,
bool kern)
{
struct sock *sk1 = sock->sk;
int err = -EINVAL; /* 执行传输层的accept操作 */
struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err, kern); if (!sk2)
goto do_err; lock_sock(sk2); /* rps处理 */
sock_rps_record_flow(sk2);
WARN_ON(!(( << sk2->sk_state) &
(TCPF_ESTABLISHED | TCPF_SYN_RECV |
TCPF_CLOSE_WAIT | TCPF_CLOSE))); /* 控制块连接到新的socket */
sock_graft(sk2, newsock); /* 设置新socket的状态为连接 */
newsock->state = SS_CONNECTED;
err = ;
release_sock(sk2);
do_err:
return err;
}
EXPORT_SYMBOL(inet_accept);

TCP层对于accept的实现,请移步另外一篇文章:<TCP层accept系统调用的实现分析>;

accept系统调用的更多相关文章

  1. accept系统调用内核实现

    用户态对accept的标准使用方法: if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_siz ...

  2. TCP层accept系统调用的实现分析

    inet_csk_accept函数实现了tcp协议accept操作,其主要完成的功能是,从已经完成三次握手的队列中取控制块,如果没有已经完成的连接,则需要根据阻塞标记来来区分对待,若非阻塞则直接返回, ...

  3. Linux进程间通信(八):流套接字 socket()、bind()、listen()、accept()、connect()、read()、write()、close()

    前面说到的进程间的通信,所通信的进程都是在同一台计算机上的,而使用socket进行通信的进程可以是同一台计算机的进程,也是可以是通过网络连接起来的不同计算机上的进程.通常我们使用socket进行网络编 ...

  4. linux独有的sendfile系统调用--“零拷贝,高效”

    参考:http://blog.csdn.net/caianye/article/details/7576198 如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰 ...

  5. socket编程之accept()函数【转载】

    名称 accept() 接收一个套接字中已建立的连接 使用格式 #include <sys/types.h> #include <sys/socket.h> int accep ...

  6. Netty源码细节-accept、read(Linux os层 + Netty层代码细节)(转)

    原文:http://budairenqin.iteye.com/blog/2215899 这篇分析一下accept的细节, 我觉得网络IO相关开发很多时候不能仅仅局限于java层, 尤其从accept ...

  7. 从Linux源码看Socket(TCP)的accept

    从Linux源码看Socket(TCP)的accept 前言 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 今天笔者就从Linux源码的角度看下Serve ...

  8. socket 函数

    1.创建套接字并返回一个描述符,该描述符可以用来访问套接字 #include<sys/types.h> #include<sys/socket.h>  int socket(i ...

  9. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

随机推荐

  1. 关于AC自动机和DP的联系

    首先是描述个大概.不说一些特殊的DP 或者借用矩阵来状态转移 (这些本质都是一样的). 只讲AC自动机和DP的关系(个人理解). AC自动机 又可以叫做状态机. 我一开始的认为.AC 自动机提供了一些 ...

  2. 【poj3016】 K-Monotonic

    http://poj.org/problem?id=3016 (题目链接) 题意 给出一个数列,将一个数${a_i}$更改为${b_i}$的代价为${|a_i-b_i|}$.求将数列改为不递减的最小代 ...

  3. IDEA的强大

    由于朋友推荐,转战IDEA数日,发现一个字就是,牛,完爆任何开发工具,让你代码上瘾的工具. 它集合了所有的开发所需要的东西,且智能化方便,适合开发有一定经验的人去使用,你会爱上它. 下面是快捷键的使用 ...

  4. Java之IO流(字节流,字符流)

    IO流和Properties IO流 IO流是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键, 因而所有 I/O 的主体实际上是内置在操作系统中的.单独的 ...

  5. BZOJ 1391 [Ceoi2008]order

    1391: [Ceoi2008]order Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完 ...

  6. EndNote文献悬挂缩进的设置方法及设置参考文献序号后面空格长度

    一.EndNote文献悬挂缩进的设置方法 写论文时使用EndNote来插入和管理参考文献是一种非常方便的方法,但有时不同的杂志要求插入的文献要求第二行缩进格式,或者不缩进. 1.在EndNote中Ed ...

  7. python 中__getitem__ 和 __iter__ 的区别

    # -*- coding: utf-8 -*- class Library(object): def __init__(self): self.books = { 'title' : 'a', 'ti ...

  8. Hadoop部署方式-伪分布式(Pseudo-Distributed Mode)

    Hadoop部署方式-伪分布式(Pseudo-Distributed Mode) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.下载相应的jdk和Hadoop安装包 JDK:h ...

  9. python2(中文编码问题):UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1

    python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错UnicodeDecodeError: 'ascii' codec can't deco ...

  10. 搞ACM的你伤不起[转载] 原作者:RoBa

    劳资六年前开始搞ACM啊!!!!!!!!!! 从此踏上了尼玛不归路啊!!!!!!!!!!!! 谁特么跟劳资讲算法是程序设计的核心啊!!!!!! 尼玛除了面试题就没见过用算法的地方啊!!!!!! 谁再跟 ...