7.2 Shutdown系统调用

本文介绍了Linux系统中shutdown系统调用如何用于关闭TCP连接,详细解析了内核函数和其在不同阶段如何操作。当连接未完成建立时,shutdown会触发tcp_disconnect断开连接;在连接建立后,根据应用进程选择的关闭模式,shutdown可能在tcp_recvmsg中返回,不读取数据。此外,close系统调用也可实现同时关闭读写并释放socket资源。
摘要由CSDN通过智能技术生成
        当应用进程不想再接收数据时,就可以关闭TCP连接。关闭的方式有两种:如果进程既不想发送数据,也不想接收数据,则可以选择完全关闭;如果进程不想发送数据,但仍可以接收数据,可以执行“半关闭”。

        关闭TCP连接可以使用shutdown系统调用:

int shutdown(int sockfd, int how);
        sockfd是要关闭的TCP socket的文件描述符,how是用来指定关闭方式:为SHUT_RD则关闭收包,为SHUT_WR则关闭发包,为SHUT_RDWR则都关闭。

        shutdown系统调用对应的内核函数为:


1932 SYSCALL_DEFINE2(shutdown, int, fd, int, how)
1933 {
1934     int err, fput_needed;
1935     struct socket *sock;
1936
1937     sock = sockfd_lookup_light(fd, &err, &fput_needed);
1938     if (sock != NULL) {  
1939         err = security_socket_shutdown(sock, how);
1940         if (!err)
1941             err = sock->ops->shutdown(sock, how); //指向inet_shutdown函数
1942         fput_light(sock->file, fput_needed);
1943     }
1944     return err;
1945 }
            inet_shutdown函数:
 811 int inet_shutdown(struct socket *sock, int how)
 812 {   
 813     struct sock *sk = sock->sk;
 814     int err = 0;   
 815     
 816     /* This should really check to make sure
 817      * the socket is a TCP socket. (WHY AC...)
 818      */
 819     how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
 820                1->2 bit 2 snds.         
 821                2->3 */
 822     if ((how & ~SHUTDOWN_MASK) || !how) /* MAXINT->0 */
 823         return -EINVAL;
 824     
 825     lock_sock(sk);
 826     if (sock->state == SS_CONNECTING) {  //连接建立尚未完成
 827         if ((1 << sk->sk_state) &
 828             (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
 829             sock->state = SS_DISCONNECTING;
 830         else
 831             sock->state = SS_CONNECTED;
 832     }
 833     
 834     switch (sk->sk_state) {
 835     case TCP_CLOSE:
 836         err = -ENOTCONN;
 837         /* Hack to wake up other listeners, who can poll for
 838            POLLHUP, even on eg. unconnected UDP sockets -- RR */
 839     default: //TCP_ESTABLISHED状态下关闭连接会到达这里
 840         sk->sk_shutdown |= how;
 841         if (sk->sk_prot->shutdown)
 842             sk->sk_prot->shutdown(sk, how); //指向tcp_shutdown
 843       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值