- 论坛徽章:
- 17
|
回复 1# Huntsmen
tcp_write_timeout,它用来判断重传次数是否已经到了。这里主要分为两个分支,一个是状态为syn_sent或者syn_recv状态,一个是另外的状态。而这里系统设置的重传次数一共有4种。
1 sysctl_tcp_syn_retries,它表示syn分节的重传次数。
2 sysctl_tcp_retries1 它表示的是最大的重试次数,当超过了这个值,我们就需要检测路由表了。
3 sysctl_tcp_retries2 这个值也是表示重试最大次数,只不过这个值一般要比上面的值大。和上面那个不同的是,当重试次数超过这个值,我们就必须放弃重试了。
4 sysctl_tcp_orphan_retries 主要是针对孤立的socket(也就是已经从进程上下文中删除了,可是还有一些清理工作没有完成).对于这种socket,我们重试的最大的次数就是它。
下面来看代码:
Java代码
static int tcp_write_timeout(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
///retry_untry表示我们需要重传的最大次数。
int retry_until;
///判断socket状态。
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
if (icsk->icsk_retransmits)
dst_negative_advice(&sk->sk_dst_cache);
///设置重传最大值
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
} else {
///是否需要检测路由表。
if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);
dst_negative_advice(&sk->sk_dst_cache);
}
///设置重传最大次数为sysctl_tcp_retries2
retry_until = sysctl_tcp_retries2;
if (sock_flag(sk, SOCK_DEAD)) {
///表示是一个孤立的socket。
const int alive = (icsk->icsk_rto < TCP_RTO_MAX);
///从tcp_orphan_retries(这个函数中会通过sysctl_tcp_orphan_retries来进行计算)中取得重传最大次数。
retry_until = tcp_orphan_retries(sk, alive);
if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
return 1;
}
}
///最终进行判断,如果重传次数已到则返回1,否则为0.
if (icsk->icsk_retransmits >= retry_until) {
/* Has it gone just too far? */
tcp_write_err(sk);
return 1;
}
return 0;
}
static int tcp_write_timeout(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
///retry_untry表示我们需要重传的最大次数。
int retry_until;
///判断socket状态。
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
if (icsk->icsk_retransmits)
dst_negative_advice(&sk->sk_dst_cache);
///设置重传最大值
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
} else {
///是否需要检测路由表。
if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
/* Black hole detection */
tcp_mtu_probing(icsk, sk);
dst_negative_advice(&sk->sk_dst_cache);
}
///设置重传最大次数为sysctl_tcp_retries2
retry_until = sysctl_tcp_retries2;
if (sock_flag(sk, SOCK_DEAD)) {
///表示是一个孤立的socket。
const int alive = (icsk->icsk_rto < TCP_RTO_MAX);
///从tcp_orphan_retries(这个函数中会通过sysctl_tcp_orphan_retries来进行计算)中取得重传最大次数。
retry_until = tcp_orphan_retries(sk, alive);
if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
return 1;
}
}
///最终进行判断,如果重传次数已到则返回1,否则为0.
if (icsk->icsk_retransmits >= retry_until) {
/* Has it gone just too far? */
tcp_write_err(sk);
return 1;
}
return 0;
}
请参考:
http://blog.csdn.net/onelight1997/article/details/7334455
http://blog.csdn.net/zhangskd/article/details/7196707
http://blog.csdn.net/admyww/article/details/5596775 |
|