客户端状态机如何进入ESTABLISHED

<span style="font-size:32px;">结论</span>

     tcp客户端connect发起之后,协议栈就会发送SYN给服务器,协议栈收到来自服务器的响应后,发出Ack后,就进入了established
   tcp服务器在收到SYN后,发送SYN+ACK后就进入SYN_RECVD,再次收到客户端的Ack时,也进入established
   established状态连接的双方进入的时机是有先后的,客户端是先进入的,服务器是后进入的

connect系统调用过程

 SYSCALL_DEFINE2(socketcall)(net/socket.c)

    SYSCALL_DEFINE3(connect)(net/socket.c)

    inet_stream_connect(net/ipv4/af_inet.c)

    tcp_v4_connect(net/ipv4/tcp_ipv4.c)

    {

         ......

         tcp_set_state(sk, TCP_SYN_SENT);

         .......

    }

    tcp_connect(net/ipv4/tcp_output.c)

    inet_wait_for_connect(net/ipv4/af_inet.c)

    {

    //一直在等待状态变化,或者是established,close,循环才会出来
	while ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
		release_sock(sk);
		timeo = schedule_timeout(timeo);
		lock_sock(sk);
		if (signal_pending(current) || !timeo)
			break;
		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
	}
	finish_wait(sk->sk_sleep, &wait);
	return timeo;
    }

状态如何变化为Established

    tcp_v4_rcv(net/ipv4/tcp_ipv4.c)

    tcp_v4_do_rcv(net/ipv4/tcp_ipv4.c)

    tcp_rcv_state_process(net/ipv4/tcp_input.c)

    tcp_rcv_synsent_state_process(net/ipv4/tcp_input.c)

   {
         ....
         TCP_ECN_rcv_synack(tp, th);
          tcp_set_state(sk, TCP_ESTABLISHED);
          if (!sock_flag(sk, SOCK_DEAD)) 
          {
                     sk->sk_state_change(sk);//唤醒等待的进程
                     sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
          }       
          ......
          tcp_send_ack(sk);
          ....
    }

      收到来自服务器的SYN+ACK,就会进入ESTABLISHED状态,然后发送ACK给服务器

  

另外补充一下状态机的认识

      主动关闭的一方,不能期待对方马上关闭,因为对方可能还有数据要传输

      多以Peer端要等待关闭close_wait

      主动关闭的一方需要等待对方的fin,所以要进入fin_wait

      以及为了避免对方重传的fin来关闭新的连接,一定要经过time_wait周期后之链路上面非常干净

       time_wait也可以避免seq序号的回绕

    

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值