• 握手6


    当服务器端接收到该报文后,处理流程和上边一样,会唤醒阻塞在该sock 上的接口,通知进程可以对该文件进行读写。

    下面服务器端会调用 accept 函数,该函数的主要作用是从已经实现过三次握手的sock 中取出一个sock,来进行通信。

    /*
     * This will accept the next outstanding connection.
     */
    struct sock *inet_csk_accept(struct sock *sk, int flags, int *err)
    {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct request_sock_queue *queue = &icsk->icsk_accept_queue;
        struct sock *newsk;
        struct request_sock *req;
        int error;
    
        lock_sock(sk);
    
        /* We need to make sure that this socket is listening,
         * and that it has something pending.
         */
        error = -EINVAL;
        if (sk->sk_state != TCP_LISTEN)
            goto out_err;
    
        /* Find already established connection */
        if (reqsk_queue_empty(queue)) {
            long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
    
            /* If this is a non blocking socket don't sleep */
            error = -EAGAIN;
            if (!timeo)
                goto out_err;
    
            error = inet_csk_wait_for_connect(sk, timeo);
            if (error)
                goto out_err;
        }
        req = reqsk_queue_remove(queue);// 从已完成的连接队列中移除。
        newsk = req->sk;
    
        sk_acceptq_removed(sk);
        if (sk->sk_protocol == IPPROTO_TCP && queue->fastopenq != NULL) {
            spin_lock_bh(&queue->fastopenq->lock);
            if (tcp_rsk(req)->listener) {
                /* We are still waiting for the final ACK from 3WHS
                 * so can't free req now. Instead, we set req->sk to
                 * NULL to signify that the child socket is taken
                 * so reqsk_fastopen_remove() will free the req
                 * when 3WHS finishes (or is aborted).
                 */
                req->sk = NULL;
                req = NULL;
            }
            spin_unlock_bh(&queue->fastopenq->lock);
        }
    out:
        release_sock(sk);
        if (req)
            __reqsk_free(req);
        return newsk;// 返回一个用于通信的 sock
    out_err:
        newsk = NULL;
        req = NULL;
        *err = error;
        goto out;
    }

    至此双方的 sock 都处于 TCP_ESTABLISHED 状态,可以用于通信喽。

  • 相关阅读:
    在Delphi中如何创建和使用udl文件
    《深入浅出struts》读书笔记(2)
    指针与数组
    《深入浅出struts》读书笔记
    《深入浅出struts》读书笔记(3)
    《深入浅出struts》读书笔记(3)
    指针的简单使用
    指针的简单使用
    指针与数组
    《深入浅出struts》读书笔记
  • 原文地址:https://www.cnblogs.com/guoyu1024/p/10597167.html
Copyright © 2020-2023  润新知