zoukankan      html  css  js  c++  java
  • 握手5

    当发现 tcp 头部的 ACK 为 1 ,则进入下面函数处理 ,重点看一下:tcp_finish_connect

    void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
    {
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
    
        tcp_set_state(sk, TCP_ESTABLISHED);// 设置 sock 的状态 为 TCP_ESTABLISHED 
    
        if (skb != NULL) {
            icsk->icsk_af_ops->sk_rx_dst_set(sk, skb);
            security_inet_conn_established(sk, skb);
        }
    
        /* Make sure socket is routed, for correct metrics.  */
        icsk->icsk_af_ops->rebuild_header(sk);
    
        tcp_init_metrics(sk);
    
        tcp_init_congestion_control(sk);
    
        /* Prevent spurious tcp_cwnd_restart() on first data
         * packet.
         */
        tp->lsndtime = tcp_time_stamp;
    
        tcp_init_buffer_space(sk);
    
        if (sock_flag(sk, SOCK_KEEPOPEN))
            inet_csk_reset_keepalive_timer(sk, keepalive_time_when(tp));
    
        if (!tp->rx_opt.snd_wscale)
            __tcp_fast_path_on(tp, tp->snd_wnd);
        else
            tp->pred_flags = 0;
    
        if (!sock_flag(sk, SOCK_DEAD)) {
            sk->sk_state_change(sk);//默认函数为 sock_def_wakeup
    1. sock状态改变时调用,比如从TCP_SYN_SENT或TCP_SYN_RECV变为TCP_ESTABLISHED, 
    2. * 导致connect()的唤醒。比如从TCP_ESTABLISHED变为TCP_CLOSE_WAIT
    
            sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);// 用来将SIGIO或SIGURG信号发送给在该套接口上的进程,通知该进程可以对该文件进行读或写.
        }
    }

    对 sock 的状态修改完后 会效用如下函数

    void tcp_send_ack(struct sock *sk)
    {
        struct sk_buff *buff;
    
        /* If we have been reset, we may not send again. */
        if (sk->sk_state == TCP_CLOSE)
            return;
    
        tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
    
        /* We are not putting this on the write queue, so
         * tcp_transmit_skb() will set the ownership to this
         * sock.
         */
        buff = alloc_skb(MAX_TCP_HEADER, sk_gfp_atomic(sk, GFP_ATOMIC));
        if (buff == NULL) {
            inet_csk_schedule_ack(sk);
            inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
            inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
                          TCP_DELACK_MAX, TCP_RTO_MAX);
            return;
        }
    
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(buff, MAX_TCP_HEADER);
        tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPHDR_ACK);
    
        /* Send it off, this clears delayed acks for us. */
        skb_mstamp_get(&buff->skb_mstamp);
        tcp_transmit_skb(sk, buff, 0, sk_gfp_atomic(sk, GFP_ATOMIC));
    }

    构造一个 tcp 报文发送给服务器端。

  • 相关阅读:
    前端编程之jQuery
    当nfs-server宕机后,client端执行 df -h hang
    git 设置默认推送和拉去的分支
    python2 中字符串转成字典后汉字出现乱码
    1.in_k8s
    部署etcd中使用ansible进行变量初始化
    获取aliyun固定类型的domain记录并输出到文件
    jumpserver 1.3x 版本忘记MFA的如何解决
    pistat 查看进程状态
    iostat 命令
  • 原文地址:https://www.cnblogs.com/guoyu1024/p/10597066.html
Copyright © 2011-2022 走看看