tcp connection setup的实现(三)
2009-09-10 00:00:00 来源:WEB开发网然后来看tcp_rcv_synsent_state_process中的状态变化:
Java代码
static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
struct tcphdr *th, unsigned len)
{
..................
if (th->ack) {
....................................
///如果是rst分节,则进行相关处理,
if (th->rst) {
tcp_reset(sk);
goto discard;
}
///如果过来的ack分节没有syn分节则直接丢掉这个包,然后返回.
if (!th->syn)
goto discard_and_undo;
..................................................
///如果校验都通过则设置状态为TCP_ESTABLISHED,下面就会发送最后一个ack分节.
tcp_set_state(sk, TCP_ESTABLISHED);
.......................................
}
....................................................
if (th->syn) {
///如果只有syn分节,则此时设置状态为TCP_SYN_RECV.
tcp_set_state(sk, TCP_SYN_RECV);
...................................
///发送ack分节给对方.
tcp_send_synack(sk);
goto discard;
#endif
}
...................
}
这里如果只接受到syn,则三次握手还没完成,我们还在等待最后一个ack,因此此时有数据报的话,会再次落入tcp_rcv_state_process函数:
Java代码
if (th->ack) {
///是否这个ack可被接受.
int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH);
switch (sk->sk_state) {
case TCP_SYN_RECV:
if (acceptable) {
tp->copied_seq = tp->rcv_nxt;
smp_mb();
///设置为TCP_ESTABLISHED,三次握手完成.
tcp_set_state(sk, TCP_ESTABLISHED);
sk->sk_state_change(sk);
///唤醒休眠在connect的队列.
if (sk->sk_socket)
sk_wake_async(sk,
SOCK_WAKE_IO, POLL_OUT);
........................................
} else {
return 1;
}
break;
Tags:tcp connection setup
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接