前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux tcp/ip 源码分析 - shutdown

Linux tcp/ip 源码分析 - shutdown

作者头像
KINGYT
修改2019-06-11 15:35:31
1.6K0
修改2019-06-11 15:35:31
举报

之前的文章已经分析了tcp的建立过程以及tcp读和写,下面我们继续看下shutdown方法。

代码语言:javascript
复制
// net/socket.c
SYSCALL_DEFINE2(shutdown, int, fd, int, how)
{
  int err, fput_needed;
  struct socket *sock;

  sock = sockfd_lookup_light(fd, &err, &fput_needed);
  if (sock != NULL) {
    ...
    if (!err)
      err = sock->ops->shutdown(sock, how);
    ...
  }
  return err;
}

该方法先根据fd找到对应的socket,再调用sock->ops->shutdown指向的方法继续执行shutdown逻辑。

由第一篇文章我们可以知道,sock->ops->shutdown指向的方法是inet_shutdown。

代码语言:javascript
复制
// net/ipv4/af_inet.c
int inet_shutdown(struct socket *sock, int how)
{
  struct sock *sk = sock->sk;
  ...
  switch (sk->sk_state) {
  ...
  default:
    sk->sk_shutdown |= how;
    if (sk->sk_prot->shutdown)
      sk->sk_prot->shutdown(sk, how);
    break;
  ...
  }

  /* Wake up anyone sleeping in poll. */
  sk->sk_state_change(sk);
  ...
  return err;
}
EXPORT_SYMBOL(inet_shutdown);

方法描述

1. 将shutdown类型how标记到sk->sk_shutdown字段。

2. 调用sk->sk_prot->shutdown指向的方法继续执行shutdown逻辑。

3. 调用sk->sk_state_change方法,唤醒那些在监听sock状态变化的阻塞线程。

由第一篇文章可以知道,sk->sk_prot->shutdown指向的方法为tcp_shutdown。

代码语言:javascript
复制
// net/ipv4/tcp.c
void tcp_shutdown(struct sock *sk, int how)
{
  ...
  if (!(how & SEND_SHUTDOWN))
    return;

  /* If we've already sent a FIN, or it's a closed state, skip this. */
  if ((1 << sk->sk_state) &
      (TCPF_ESTABLISHED | TCPF_SYN_SENT |
       TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) {
    /* Clear out any half completed packets.  FIN if needed. */
    if (tcp_close_state(sk))
      tcp_send_fin(sk);
  }
}
EXPORT_SYMBOL(tcp_shutdown);

方法描述

1. 如果shutdown类型how中,不包括SEND_SHUTDOWN,即只包括RCV_SHUTDOWN,则不用再执行其他逻辑,直接返回就好。

当我们在调用shutdown方法时,如果只指定RCV_SHUTDOWN,最终结果只是标记sk->sk_shutdown字段,使其值包含RCV_SHUTDOWN,并不会再执行其他tcp逻辑。

2. 检查sk->sk_state字段状态,判断是否已经发送了fin消息,或者是否已经是closed状态,如果是,也不用再继续了。

3. 调用tcp_close_state方法,根据当前sk->sk_state的状态,设置其下一状态,比如,如果当前状态为TCP_ESTABLISHED,则下一状态应该为TCP_FIN_WAIT1,之后该方法返回是否需要发送fin消息。

4. 如果需要,则发送fin消息给对方。

完。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linux内核及JVM底层相关技术研究 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档