快速业务通道

tcp连接在断网后的恢复能力

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-26
allocation);

  836 if (!skb)

  837 goto wait_for_memory;

  831行判断sndbuf里还有没有空间,如果没有,跳到wait_for_sndbuf

  [net/ipv4/tcp.c --> tcp_recvmsg]

  958 wait_for_sndbuf:

  959 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);

  960 wait_for_memory:

  961 if (copied)

  962 tcp_push(sk, tp, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);

  963

  964 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)

Empire CMS,phome.net

  965 goto do_error;

  966

  967 mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));

  968 }

  969 }

  970

  971 out:

  972 if (copied)

  973 tcp_push(sk, tp, flags, mss_now, tp->nonagle);

  974 TCP_CHECK_TIMER(sk);

  975 release_sock(sk);

  976 return copied;

  977

  978 do_fault:

  979 if (!skb->len) {

  980 if (sk->sk_send_head == skb)

  981 sk->sk_send_head = NULL;

  982 __skb_unlink(skb, skb->list);

  983 sk_stream_free_skb(sk, skb);

  984 }

  985

  986 do_error:

  987 if (copied)

  988 goto out;

  989 out_err:

  990 err = sk_stream_error(sk, flags, err);

  991 TCP_CHECK_TIMER(sk);

  992 release_sock(sk);

  993 return err;

  sndbuf 不够,于是设个bit位,961行的判断不成立,这会儿还啥也没发送,copied为0.继续,执行sk_stream_wait_memory,顾名思义,它是等snbbuf有可用空间,但是我们的socket是设了NONBLOCK的,sk_stream_wait_memory很快返回,并设返回值为-EAGAIN.,又要跳到do_error,987行的判断依然不成立,于是到了out_err,带着-EAGAIN离开 tcp_recvmsg函数.

  这就是我们不停send,却返回结果为0且errno为EAGAIN的原因.

  如果一切正常,socket不停的往外发数据,早晚sndbuf会出现可用空间的.但如果异常呢?比如设了TCP_NODELAY而网络又断了,那就瞬间会发送大量的包,对端却没有ACK.

  我们再看看如果正常,tcp_sendmsg会如何:832行的跳转是不会发生了,于是,程序继续往下(略去一部分skb的操作代码)

  [net/ipv4/tcp.c --> tcp_sendmsg]

  936 if (!copied)

  937 TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;

  938

  939 tp->write_seq = copy;

  940 TCP_SKB_CB(skb)->end_seq = copy;

  941 skb_shinfo(skb)->tso_segs = 0;

Empire CMS,phome.net

  942

  943 from = copy;

  944 copied = copy;

  945 if ((seglen -= copy) == 0 && iovlen == 0)

  946 goto out;

  如果这一把就把消息全放进了skb,且iovec也轮完了,此时945行的判断就生效了,直接跳转out,执行tcp_push.tcp_push调用__tcp_push_pending_frame:

  [net/ipv4/tcp.h --> __tcp_push_pending_frame]

  1508 static __inline__ void __tcp_push_pending_frames(struct sock *sk,

  1509 struct tcp_opt *tp,

  1510 unsigned cur_mss,

  1511

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号