zoukankan      html  css  js  c++  java
  • 套接字之shutdown系统调用

    shutdown用来关闭一个全双工连接的部分或者全部,比如关闭读,关闭写,或者读写全部关闭;

     1 /*
     2  *    Shutdown a socket.
     3  */
     4 
     5 SYSCALL_DEFINE2(shutdown, int, fd, int, how)
     6 {
     7     int err, fput_needed;
     8     struct socket *sock;
     9 
    10     /* 找到socket */
    11     sock = sockfd_lookup_light(fd, &err, &fput_needed);
    12     if (sock != NULL) {
    13         err = security_socket_shutdown(sock, how);
    14         if (!err)
    15             /* 调用对应类型的shutdown */
    16             err = sock->ops->shutdown(sock, how);
    17         fput_light(sock->file, fput_needed);
    18     }
    19     return err;
    20 }

    inet_shutdown会根据连接的状态进行不同的处理,比如已连接状态需要调用传输层实现的shutdown,而监听或者发送了syn包会根据情况则调用传输层的disconnect等;

     1 /* 关闭操作 */
     2 int inet_shutdown(struct socket *sock, int how)
     3 {
     4     struct sock *sk = sock->sk;
     5     int err = 0;
     6 
     7     /* This should really check to make sure
     8      * the socket is a TCP socket. (WHY AC...)
     9      */
    10     how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
    11                1->2 bit 2 snds.
    12                2->3 */
    13     /* how值错误 */
    14     if ((how & ~SHUTDOWN_MASK) || !how)    /* MAXINT->0 */
    15         return -EINVAL;
    16 
    17     lock_sock(sk);
    18 
    19     /* 正在连接 */
    20     if (sock->state == SS_CONNECTING) {
    21         /* syn发送,syn接收,关闭状态 */
    22         if ((1 << sk->sk_state) &
    23             (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
    24             /* 设置正在关闭连接 */
    25             sock->state = SS_DISCONNECTING;
    26         /* 否则为已连接状态 */
    27         else
    28             sock->state = SS_CONNECTED;
    29     }
    30 
    31     switch (sk->sk_state) {
    32     case TCP_CLOSE:
    33         err = -ENOTCONN;
    34         /* Hack to wake up other listeners, who can poll for
    35            POLLHUP, even on eg. unconnected UDP sockets -- RR */
    36     default:
    37         /* 设置how值,并且调用传输层的shutdown */
    38         sk->sk_shutdown |= how;
    39         if (sk->sk_prot->shutdown)
    40             sk->sk_prot->shutdown(sk, how);
    41         break;
    42 
    43     /* Remaining two branches are temporary solution for missing
    44      * close() in multithreaded environment. It is _not_ a good idea,
    45      * but we have no choice until close() is repaired at VFS level.
    46      */
    47     case TCP_LISTEN:
    48         /* 监听状态,如果无接收方向的关闭操作,跳出 */
    49         if (!(how & RCV_SHUTDOWN))
    50             break;
    51         /* 有接收方向的关闭,继续 */
    52         /* Fall through */
    53     case TCP_SYN_SENT:
    54         /* 调用传输层的disconnect断开连接 */
    55         err = sk->sk_prot->disconnect(sk, O_NONBLOCK);
    56 
    57         /* 调增状态 */
    58         sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
    59         break;
    60     }
    61 
    62     /* Wake up anyone sleeping in poll. */
    63     /* 状态改变,唤醒等待的进程 */
    64     sk->sk_state_change(sk);
    65     release_sock(sk);
    66     return err;
    67 }

    tcp层shutdown实现请移步下面文章<TCP层shutdown系统调用的实现分析>;

  • 相关阅读:
    android ListView 获取点击的选项
    架构流程笔记
    关键字搜索
    利用HttpWebRequest模拟提交图片
    (一)phonegap自学---不会java也会写原生app
    js正则笔记
    jQuery插件编写,
    存储过程分页
    JavaScript中的this陷阱
    jQuery.Deferred(jQuery1.5-2.1)源码剖析
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/7623072.html
Copyright © 2011-2022 走看看