加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码门户网 (https://www.92codes.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[十六]:TCP三次握手

发布时间:2016-09-28 12:48:07 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核:2.6.34 TCP是应用最广泛的传输层协议,其提供了面向连接的、可靠的字节流服务,但 也正是因为这些特性,使得TCP较之UDP异常复杂,还是分两部分[创建与使用]来进行分析。这篇主要包括TCP的创建及三次握手 的过程。 编程时一般用如下语句创建

查找到达[daddr, dport]的路由项,路由项的查找与更新与”路由表”章节所 述一样。要注意的是由于是作为客户端调用,创建socket后调用connect,因而saddr, sport都是0,同样在未查找路由前,要走 的出接口oif也是不知道的,因此也是0。在查找完路由表后(注意不是路由缓存),可以得知出接口,但并未存储到sk中。因此插 入的路由缓存是特别要注意的:它的键值与实际值是不相同的,这个不同点就在于oif与saddr,键值是[saddr=0, sport=0, daddr, dport, oif=0],而缓存项值是[saddr, sport=0, daddr, dport, oif]。

tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,     
      RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,     
      IPPROTO_TCP,     
      inet->inet_sport, usin->sin_port, sk, 1);     
if (tmp < 0) {     
 if (tmp == -ENETUNREACH)     
  IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);     
 return tmp;     
}

通过查找到的路由项,对inet进行赋值,可以看到,除了sport,都赋予了值,sport的选择复杂点,因为它要随机从 未使用的本地端口中选择一个。

if (!inet->inet_saddr)     
 inet->inet_saddr = rt_rt_src;      
inet->inet_rcv_addr = inet->inet_saddr;     
……     
inet->inet_dport = usin->sin_port;     
inet->inet_daddr = daddr;

状态从CLOSING转到TCP_SYN_SENT,也就是我们熟知的TCP的状态转移图。

tcp_set_state(sk, TCP_SYN_SENT);

插入到bind链表中

err = inet_hash_connect(&tcp_death_row, sk); //== > __inet_hash_connect()

当 snum==0时,表明此时源端口没有指定,此时会随机选择一个空闲端口作为此次连接的源端口。low和high分别表示可用端口的下 限和上限,remaining表示可用端口的数,注意这里的可用只是指端口可以用作源端口,其中部分端口可能已经作为其它socket 的端口号在使用了,所以要循环1~remaining,直到查找到空闲的源端口。

if (!

snum) {     
 inet_get_local_port_range(&low, &high);     
 remaining = (high - low) + 1;     
 ……     
 for (i = 1; i <= remaining; i++) {     
……// choose a valid port     
}     
}

(编辑:源码门户网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读