假设两台设备双方均发送syn给对端,在发送syn之后状态处于SYN_SENT状态,此时双方均收到对端的发来的syn,则立即进入SYN_RECV状态,并且都向对端回复syn+ack,在收到syn+ack之后,连接从SYN_RECV状态切换到ESTABLISHED状态;

在发送syn进入SYN_SENT状态之后,收到对端发来的syn包处理流程如下,调用tcp_set_state(sk, TCP_SYN_RECV)进入SYN_RECV状态,以及调用tcp_send_synack(sk)向对端发送syn+ack;

 static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
const struct tcphdr *th)
{
if (th->syn) {
/* We see SYN without ACK. It is attempt of
* simultaneous connect with crossed SYNs.
* Particularly, it can be connect to self.
*/
tcp_set_state(sk, TCP_SYN_RECV); if (tp->rx_opt.saw_tstamp) {
tp->rx_opt.tstamp_ok = ;
tcp_store_ts_recent(tp);
tp->tcp_header_len =
sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
} else {
tp->tcp_header_len = sizeof(struct tcphdr);
} tp->rcv_nxt = TCP_SKB_CB(skb)->seq + ;
tp->copied_seq = tp->rcv_nxt;
tp->rcv_wup = TCP_SKB_CB(skb)->seq + ; /* RFC1323: The window in SYN & SYN/ACK segments is
* never scaled.
*/
tp->snd_wnd = ntohs(th->window);
tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
tp->max_window = tp->snd_wnd; tcp_ecn_rcv_syn(tp, th); tcp_mtup_init(sk);
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
tcp_initialize_rcv_mss(sk); tcp_send_synack(sk);
}

在SYN_RECV状态收到对端发来的syn+ack包,则直接进入ESTABLISHED已连接状态;

 int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
{
/* step 5: check the ACK field */
acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
FLAG_UPDATE_TS_RECENT) > ; switch (sk->sk_state) {
case TCP_SYN_RECV: /* ack处理失败 */
if (!acceptable)
return ; /* RTT */
if (!tp->srtt_us)
tcp_synack_rtt_meas(sk, req); /* Once we leave TCP_SYN_RECV, we no longer need req
* so release it.
*/
if (req) {
inet_csk(sk)->icsk_retransmits = ;
reqsk_fastopen_remove(sk, req, false);
} else {
/* Make sure socket is routed, for correct metrics. */
/* 检查重建路由 */
icsk->icsk_af_ops->rebuild_header(sk);
/* 初始化拥塞邋控制 */
tcp_init_congestion_control(sk);
/* 路径mtu发现初始化 */
tcp_mtup_init(sk);
/* 用户待读取数据初始化 */
tp->copied_seq = tp->rcv_nxt;
/* 调整接收发送缓存以及窗口等 */
tcp_init_buffer_space(sk);
}
smp_mb(); /* 连接更新为已连接状态 */
tcp_set_state(sk, TCP_ESTABLISHED);
sk->sk_state_change(sk);
/* 省略了一些代码 */
}

最新文章

  1. 微信学习总结 02 ngrok 部署本机代码,使外网可以访问
  2. matlab工具箱之人眼检测+meanshift跟踪算法--人眼跟踪
  3. [转载]python操作excel使用win32com
  4. Floyd算法(一)之 C语言详解
  5. Java总结篇系列:Java多线程(三)
  6. archlinux 下 nignx + php 出现 no input file specified
  7. 为 Macbook 安装 wget 命令
  8. C# 线程(四):生产者和消费者
  9. java 简单的词法分析
  10. 集团财务分析BI项目中的财务系统环境
  11. Django剖析
  12. codeforces 755C. PolandBall and Forest
  13. IOS应用FFMPEG库
  14. AJAX跨域完全讲解
  15. CTF--web 攻防世界web题 get_post
  16. vue2上传图片到OSS
  17. Mission Impossible 6
  18. 题解 P5239 【回忆京都】
  19. Java 调用 groovy 脚本文件,groovy 访问 MongoDB
  20. Python -- Scrapy 框架简单介绍(Scrapy 安装及项目创建)

热门文章

  1. 从零开始搭建react应用
  2. 转:idea类名出现了不同的颜色
  3. php--常见算法3
  4. Delphi 图像组件(Image)
  5. 解决remix在线编译器连接本地私有链环境不成功的问题
  6. Introduction to Restricted Boltzmann Machines
  7. Linux之apt-get软件管理
  8. Windowsx下Appium环境搭建步骤及问题
  9. linux weblogic的sh文件
  10. 服务器syns to listen sockets drop导致创建socket失败