在前文的inet_accept()分析中我们知道inet_accept会通过如下方式调用传输层的accpet
int inet_accept(struct socket *sock, struct socket *newsock, int flags)
{
...
struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err)
...
}
对于tcpv4而言此函数为inet_csk_accept(),那么我们接下来自习看看此函数的实现
在分析代码前我们需要了解,套接字有监听套接字和具体通信的套接字
监听套接字的扩展结构inet_connection_sock中存在icsk_accept_queue成员,
此成员中有两个队列,一个用于完全建立连接(完成三次握手)的队列,此队列项中会包含新建的
用于通信的sock结构,在进程不在阻塞获得此sock结构后会把此队列项从完全建立连接的队列删除.此队列的最大长度即是listen(int s, int backlog)中第二个参数指定的
另一个队列是半连接队列,即还没有完成三次握手的队列项会加入到此队列,此队列项中的sock完成三次握手后会从此队列中移除,添加到完全建立连接的队列中
/**********************************************
sk:监听sock
flags:这些是文件标志, 例如 O_NONBLOCK
err:传出参数 用于接收错误
******************************************************/
struct sock *inet_csk_accept(struct sock *sk, int flags, int *err)
{
struct inet_connection_sock *icsk = inet_csk(sk