ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 从Linux源码看Socket(TCP)Client端的Connect

从Linux源码看Socket(TCP)Client端的Connect

投稿 Linux操作系统 作者:fo110041 时间:2020-09-07 10:39:36 0 删除 编辑


|->tcp_connect_init 初始化tcp socket |->tcp_transmit_skb 发送SYN包 |->inet_csk_reset_xmit_timer 设置SYN重传定时器

tcp_connect_init初始化了一大堆TCP相关的设置,例如mss_cache/rcv_mss等一大堆。而且如果开启了TCP窗口扩大选项的话,其窗口扩大因子也在此函数里进行计算:

tcp_connect_init

|-> tcp_select_initial_window
int tcp_select_initial_window (...)
{ ...... (*rcv_wscale) = 0;
if (wscale_ok) {
/* Set window scaling on max possible window
* See RFC1323 for an explanation of the limit to 14
*/
space = max_t(u32, sysctl_tcp_rmem[ 2], sysctl_rmem_max);
space = min_t(u32, space, *window_clamp);
while (space > 65535 && (*rcv_wscale) < 14) {
space >>= 1;
(*rcv_wscale)++; } } ......}

如上面代码所示,窗口扩大因子取决于Socket最大可允许的读缓冲大小和window_clamp(最大允许滑动窗口大小,动态调整)。搞完了一票初始信息设置后,才开始真正的三次握手。 在tcp_transmit_skb中才真正发送SYN包,同时在紧接着的inet_csk_reset_xmit_timer里设置了SYN超时定时器。如果对端一直不发送SYN_ACK,将会返回-ETIMEDOUT。

重传的超时时间和

/proc/sys/net/ipv4/tcp_syn_retries

息息相关,Linux默认设置为5,建议设置成3,下面是不同设置的超时时间参照图。

在设置了SYN超时重传定时器后,tcp_connnect就返回,并一路返回到最初始的inet_stream_connect。在这里我们就等待对端返回SYN_ACK或者SYN定时器超时。


int __inet_stream_connect(
struct socket *sock,...,)

{ // 如果设置了O_NONBLOCK则timeo为0
timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
......
// 如果timeo=0即O_NONBLOCK会立刻返回
// 否则等待timeo时间
if (!timeo || !inet_wait_for_connect(sk, timeo, writebias))
goto out;
}

Linux本身提供一个SO_SNDTIMEO来控制对connect的超时,不过Java并没有采用这个选项。而是采用别的方式进行connect的超时控制。仅仅就C语言的connect系统调用而言,不设置SO_SNDTIMEO,就会将对应用户进程进行睡眠,直到SYN_ACK到达或者超时定时器超时才将次用户进程唤醒。

如果是NON_BLOCK的话,则是通过select/epoll等多路复用机制去捕获超时或者连接成功事件。

对端SYN_ACK到达

在Server端SYN_ACK到达之后会按照下面的代码路径传递,并唤醒用户态进程:

tcp_v4_rcv

|->tcp_v4_do_rcv |->tcp_rcv_state_process |->tcp_rcv_synsent_state_process |->tcp_finish_connect |->tcp_init_metrics 初始化度量统计 |->tcp_init_congestion_control 初始化拥塞控制 |->tcp_init_buffer_space 初始化buffer空间 |->inet_csk_reset_keepalive_timer 开启包活定时器 |->sk_state_change(sock_def_wakeup) 唤醒用户态进程 |->tcp_send_ack 发送三次握手的最后一次握手给Server端 |->tcp_set_state(sk, TCP_ESTABLISHED) 设置为ESTABLISHED状态


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69976873/viewspace-2717560/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2020-09-02

  • 博文量
    6
  • 访问量
    2464