调用 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() 不会。

优雅地断开TCP连接相关推荐

  1. c语言 socket 断开自动连接,如何优雅地断开TCP连接?

    socket关闭: close()和shutdown()的差异 对于一个tcp连接,在c语言里一般有2种方法可以将其关闭: close(sock_fd); 或者 shutdown(sock_fd, . ...

  2. shutdown()函数:优雅地断开TCP连接

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

  3. linux断开tcp连接命令,强制断开已经连接上的tcp连接

    1.修改TCP默认 TCP 连接痴呆保持是 120 小时,也就是 5 天,可以通过tcp连接超时来断开 sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_ti ...

  4. java 断开tcp连接_处理TCP客户端断开连接

    我有这个简单的服务器,接受客户端的TCP套接字连接 . 尝试连接的每个客户端都使用新的Socket获取自己的 TCPConnectionHandler 实例 . 我不明白我该如何处理客户端断开连接 . ...

  5. go 监测tcp 连接断开_TCP三次握手和四次挥手以及11种状态

    三次握手 置位概念:根据TCP的包头字段,存在3个重要的标识ACK.SYN.FIN ACK:表示验证字段 SYN:位数置1,表示建立TCP连接 FIN:位数置1,表示断开TCP连接 三次握手过程说明: ...

  6. 【TCP专题】TCP连接断开

    当TCP的连接建立完成后,我们就可以尽情的通过TCP连接所创立的会话来进行数据的传输了.当然,再有意思的话题也有说完的时候,所以,当数据传输完之后,TCP该如何善后呢? TCP的四次挥手 TCP的连接 ...

  7. TCP连接握手为什么3次?断开为什么是4次?TCP的优化-SCTP协议

    TCP TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的.可靠的.基于字节流的传输层通信协议. 目录: TCP报头 TCP的三次握手 TCP为什么要进 ...

  8. java tcp client 断开_HttpClient出现TCP连接异常关闭发送RST包

    问题现象 在与第三方系统通过http交互数据的过程中,抓包发现每次TCP连接都是异常关闭,报文如下: 可以看到,由我方发起3次握手建立连接,然后发送http请求,对方响应数据,我方ACK后直接发RST ...

  9. TCP连接的建立与断开

    目录 TCP报文头部 TCP三次握手 TCP四次挥手 TCP报文头部 URG:紧急指针有效位. ACK:确认序列号有效位. PSH:通过接收端立即将数据提交给用户进程,不在缓存中停留. RST:RST ...

最新文章

  1. 单链表按顺序插入节点
  2. WINDOWS系统文件讲解
  3. Django 3.2.5博客开发教程:体验django模板
  4. 诺基亚报告称:到2020年北美电子邮件流量占比将跌至7%
  5. 自训练:超越预训练,展现强大互补特性的上分新范式!
  6. 23种设计模式之装饰模式
  7. api函数原型大全_如何使用您的API优先平台来使原型做好生产准备
  8. (03)System Verilog 通用总线激励驱动方法
  9. DW —— 简易计算器 (JavaScript)
  10. 二叉树 的建立及遍历 过程
  11. 网络01:双无线路由器无缝对接设置
  12. docker 安装依赖_史上最全Docker环境安装指南-让安装docker简单到爆
  13. Python规范神器(PEP8 ),Pylint是代码检查工具
  14. Heartbeat配置方案
  15. 判断一个数能否同时被3和5整除
  16. 电池寿命计算(电池放电支持时长)
  17. msvcr120.dll丢失怎样修复?msvcr120.dll文件修复方法
  18. 图片转字符画(python)
  19. 配准带尺度点云的方法汇总
  20. macbook苹果电脑新手快速上手

热门文章

  1. 【UOJ】67 新年的毒瘤 【BZOJ】1123 BLO
  2. linux下文件以及目录权限修改(摘抄)
  3. C Primer Plus note1
  4. ubuntu安装oracle数据库乱码问题解决方案(超级简单)
  5. 查看wcf服务中方法测试客户端
  6. 【原】TreeView+Checkbox级联操作(IE/FireFox测试通过)
  7. SqlConnetction类
  8. oracle给每行加上序号,Oracle 根据分类字段给查询结果添加序号
  9. C# 系统应用之Cookie\Session基础知识及php读取Cookie\Session
  10. POJ 3981.字符串替换