socket--shutdown()

调用 close()/closesocket() 函数意味着完全断开连接,即不能发送数据也不能接收数据,这种“生硬”的方式有时候会显得不太“优雅”。


图1:close()/closesocket() 断开连接


上图演示了两台正在进行双向通信的主机。主机A发送完数据后,单方面调用 close()/closesocket() 断开连接,之后主机A、B都不能再接受对方传输的数据。实际上,是完全无法调用与数据收发有关的函数。

一般情况下这不会有问题,但有些特殊时刻,需要只断开一条数据传输通道,而保留另一条。

使用 shutdown() 函数可以达到这个目的,它的原型为:

 
  1. int shutdown(int sock, int howto); //Linux
  2. int shutdown(SOCKET s, int howto); //Windows

sock 为需要断开的套接字,howto 为断开方式。

howto 在 Linux 下有以下取值:

  • SHUT_RD:断开输入流。套接字无法接收数据(即使输入缓冲区收到数据也被抹去),无法调用输入相关函数。
  • SHUT_WR:断开输出流。套接字无法发送数据,但如果输出缓冲区中还有未传输的数据,则将传递到目标主机。
  • SHUT_RDWR:同时断开 I/O 流。相当于分两次调用 shutdown(),其中一次以 SHUT_RD 为参数,另一次以 SHUT_WR 为参数。


howto 在 Windows 下有以下取值:

  • SD_RECEIVE:关闭接收操作,也就是断开输入流。
  • SD_SEND:关闭发送操作,也就是断开输出流。
  • SD_BOTH:同时关闭接收和发送操作。


至于什么时候需要调用 shutdown() 函数,下节我们会以文件传输为例进行讲解。

close()/closesocket()和shutdown()的区别

确切地说,close() / closesocket() 用来关闭套接字,将套接字描述符(或句柄)从内存清除,之后再也不能使用该套接字,与C语言中的 fclose() 类似。应用程序关闭套接字后,与该套接字相关的连接和缓存也失去了意义,TCP协议会自动触发关闭连接的操作。

shutdown() 用来关闭连接,而不是套接字,不管调用多少次 shutdown(),套接字依然存在,直到调用 close() / closesocket() 将套接字从内存清除。

调用 close()/closesocket() 关闭套接字时,或调用 shutdown() 关闭输出流时,都会向对方发送 FIN 包。FIN 包表示数据传输完毕,计算机收到 FIN 包就知道不会再有数据传送过来了。

默认情况下,close()/closesocket() 会立即向网络中发送FIN包,不管输出缓冲区中是否还有数据,而shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包。也就意味着,调用 close()/closesocket() 将丢失输出缓冲区中的数据,而调用 shutdown() 不会。

`redis-cli shutdown` 是 Redis 客户端提供的一个用于优雅地关闭 Redis 服务器的命令。当您希望安全地停止 Redis 实例时,这个命令是非常有用的工具。它可以确保所有的后台保存操作都已完成,并允许主从复制环境中的从节点有序地脱离复制链路。 以下是关于 `redis-cli shutdown` 更详细的说明: ### 命令格式 ```sh redis-cli shutdown [SAVE|NOSAVE] ``` - **SAVE**:在关机前执行 RDB 持久化操作,默认行为。 - **NOSAVE**:进行任何持久化操作直接关闭。 如果没有指定参数,则默认采用 SAVE 方式,即先执行一次完整的 RDB 快照再结束进程。如果启用了 AOF 日志记录功能(Append Only File),则还会同时刷新最新的日志条目到磁盘上。 ### 主要用途 1. **保证数据一致性**: - 使用 `shutdown save` 确保所有修改过的键值对都能被完整地存储下来,这对于防止因意外停电或其他异常情况造成的部分数据丢失非常重要。 2. **平稳切换主从角色**: - 在哨兵模式下的高可用环境中,通过合理安排各个实例的停机顺序可以减少整个系统的服务中断时间,比如首先让从节点离开复制链,之后才去处理主节点。 3. **自动化脚本集成**: - 这个命令非常适合作为 CI/CD 流水线的一部分或是定时任务里的清理工作环节,因为它能在影响其他组件的前提下干净利落地结束 Redis 服务。 ### 注意事项 - 如果 Redis 配置了密码认证,在执行该命令之前应提供正确的密码验证; - 关闭期间允许新的客户端连接建立起来; - 当有多个实例共享同一套配置文件或者监听相同的 UNIX socket/SOCK 地址时,请小心使用此命令以免误操作引起必要的麻烦。 ### 示例用法 假设我们有一个本地运行着 Redis 的服务器实例,我们可以按照下面的方式分别尝试带参数和无参数的情况来体验其效果: #### 默认保存快照后关闭 ```sh $ redis-cli shutdown # 相等于 "redis-cli shutdown SAVE" ``` #### 保存快照就关闭 ```sh $ redis-cli shutdown NOSAVE # 忽略脏缓冲区内容直至关机 ``` 以上就是对 `redis-cli shutdown` 命令的基本介绍及其应用场景的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值