shutdown()

#include <sys/socket.h>

int shutdown(int sockfd, int how);

概述

shutdown() 调用会导致与 _sockfd_ 关联的套接字上的全双工连接全部或部分关闭。如果 _how_SHUT_RD,则不允许进一步接收数据。如果 how 是 SHUT_WR,则不允许进一步发送数据。如果 howSHUT_RDWR,则不允许进一步接收和发送数据。

shutdown(SHUT_RD)

执行 shutdown(SHUT_RD) 仅关闭本地套接字的读方向功能。

本地行为

  • 丢弃接收缓冲区数据:内核会清空接收缓冲区中未读取的数据。
  • 停止接收数据:应用层通过 recv()read() 读取数据时会返回 0(EOF)。
  • 静默处理对端数据:即使对端继续发送数据,本地 TCP 协议栈会丢弃这些数据(不会进入接收缓冲区),但仍会回复 ACK 确认报文(避免对端重传)。

对端行为

  • FIN 报文:由于 SHUT_RD 不涉及写方向关闭,本地不会发送 FIN 报文,因此对端无法通过协议感知到读方向的关闭****。
  • 对端仍可发送数据:对端的 send() 操作仍会成功(数据进入发送缓冲区并通过 TCP 传输),但本地会静默丢弃这些数据。
  • 对端可能误判:若对端依赖本地的读操作反馈(如业务层协议),可能导致对端长时间等待响应,最终因超时触发连接重置(如 ECONNRESET 错误)。例如,对端(业务层协议)发送了一个消息,期望本地接收到消息后,给它一个回复。但由于本地读端已关闭,无法收到对端发送的消息,自然也不可能给他一个回复,对端(业务层协议)可能经过多次尝试失败后,判断本地已经关闭。

shutdown(SHUT_WR)

本地执行 shutdown(SHUT_WR) 会关闭本地套接字的写方向,触发 TCP 协议的四次挥手流程。

图网上随便找的。

本地行为

  1. 立即发送 FIN 报文
    调用 shutdown(SHUT_WR) 后,内核会立即发送 FIN 报文给对端,表示本地不再发送数据。此时本地套接字进入 FIN_WAIT_1 状态。
  2. 发送缓冲区处理
    • 若发送缓冲区有未发送数据,内核会尝试全部发送****。
    • 后续对套接字的写操作(如 send())会返回 -1,并设置 errnoEPIPE 或触发 SIGPIPE 信号****。
  3. 状态流转
    • 收到对端的 ACK 后,本地状态转为 FIN_WAIT_2(等待对端 FIN 报文)。
    • 收到对端 FIN 后,本地回复 ACK 并进入 TIME_WAIT 状态。

对端行为

  1. 接收 FIN 报文

    • 对端内核收到 FIN 后,标记 sk->sk_shutdown |= RCV_SHUTDOWN;,套接字进入 CLOSE_WAIT 状态,并回复 ACK。核心逻辑位于 net/ipv4/tcp_input.c 中的 tcp_fin() 函数。
    • 对端应用层的 read() 行为如下:
      • 接收缓冲区仍有数据:应用层仍可通过 read() 读取接收缓冲区中已有的数据,返回剩余数据长度。

      • 接收缓冲区没有数据:应用层 read()(无论阻塞还是非阻塞式 scoket)都会立即返回 0(EOF)。

      • 不接收新数据:若本地(主动关闭方)在发送 FIN 后仍有数据到达,读端(被动关闭方)的 TCP 协议栈会丢弃这些数据(不会进入接收缓冲区),但回复 ACK 确认包以避免重传。

        正常情况下的 read() 行为(没有收到 fin 包,更准确地说是读端未关闭的情况下)

        • **socket 阻塞模式:**无数据进程/线程阻塞;数据到达,返回实际读取字节数。
        • **scoket 非阻塞模式:**内核接收缓冲区有数据返回实际读取字节数;无数据,立即返回 -1,设置 errnoEAGAINEWOULDBLOCK
  2. 数据发送与关闭

    • 对端仍可继续发送数据,本地会接收并处理(若未关闭读方向 SHUT_RD)。
    • 对端调用 close() 时,发送自己的 FIN 报文,完成四次挥手。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值