当前位置: 首页 > news >正文

TCP半关闭

理解TCP半关闭:像水管一样的网络连接控制

从全关闭到半关闭:为什么需要这种机制?

想象你和朋友正在通电话讨论一个重要项目:

  • 全关闭:就像突然挂断电话,双方都无法再说话
  • 半关闭:你说"我说完了,你还有什么要补充的吗?"——你不再说话但还能听对方说

这正是TCP半关闭的实际意义。在网络编程中,有时我们需要这种"我说完了但还想听你说"的状态。

深入理解套接字和"流"

在这里插入图片描述

1. 什么是套接字流?

把两台主机之间的TCP连接想象成连接两个水桶的两根水管:

  • 一根水管负责A→B的数据流动(输出流)
  • 另一根负责B→A的数据流动(输入流)
  • 这两根水管共同组成了一个完整的套接字连接

2. 为什么流是单向的?

这与现实中的水管原理相同:

  • 水只能单向流动(靠压力差)
  • 要实现双向流动必须用两根独立的水管
  • 关闭其中一根不影响另一根的工作

shutdown()函数:精准的流量控制阀门

shutdown()函数就像水管上的精密阀门,可以单独关闭某一方向的流动:

#include <sys/socket.h>int shutdown(int sockfd, int how);

how参数选项

  • SHUT_RD:关闭输入流(不再接收数据)
  • SHUT_WR:关闭输出流(不再发送数据)
  • SHUT_RDWR:同时关闭(等同于close)

典型应用场景

  1. 文件传输结束通知

    • 发送方传完文件后关闭输出流
    • 但仍保持输入流接收确认消息
  2. HTTP协议

    • 客户端发送完请求后可以半关闭输出
    • 等待服务器响应
  3. 数据库查询

    • 发送完SQL语句后可以半关闭
    • 只保留接收结果的通道

文件传输实战:如何正确使用半关闭

发送方代码框架

// 1. 发送文件数据
while ((read_cnt = fread(buf, 1, BUF_SIZE, fp)) > 0) {write(sock, buf, read_cnt);
}// 2. 半关闭:通知接收方数据已发完
shutdown(sock, SHUT_WR); // 3. 接收确认消息
read(sock, buf, BUF_SIZE); 
printf("Server message: %s\n", buf);// 4. 完全关闭
close(sock);

接收方代码框架

// 1. 接收文件数据
while ((read_cnt = read(sock, buf, BUF_SIZE)) > 0) {fwrite(buf, 1, read_cnt, fp);
}// 2. 收到EOF(发送方已SHUT_WR)
printf("File transfer complete\n");// 3. 发送确认消息
write(sock, "File received", 13);// 4. 完全关闭
close(sock);

缓冲区设计的艺术

在文件传输中,缓冲区大小设置很有讲究:

  1. 不必过分追求精确

    • TCP本身会处理分包和重组
    • 常见缓冲区大小(如4K、8K)通常效果很好
  2. 平衡内存和效率

    #define BUF_SIZE 4096 // 4K缓冲区是个不错的起点
    char buf[BUF_SIZE];
    
  3. 循环读写是关键

    • 必须循环直到处理完所有数据
    • 单次读写不能假设处理了全部数据

半关闭的注意事项

  1. 资源释放

    • shutdown后仍需close释放套接字资源
    • 半关闭不是完全的资源释放
  2. 状态感知

    • 接收方read返回0表示对方已SHUT_WR
    • 这是判断半关闭的重要标志
  3. 错误处理

    if (shutdown(sock, SHUT_WR) == -1) {perror("shutdown error");// 错误处理逻辑
    }
    
  4. 协议设计

    • 应用层协议需要明确半关闭的含义
    • 避免接收方无限等待

为什么不是所有场景都需要半关闭?

就像不是所有通话都需要"你说完了吗?"的确认:

  • 简单请求-响应:不需要
  • 持续对话:不需要
  • 但以下情况很有价值:
    • 大文件传输
    • 需要明确结束标志的协议
    • 需要接收确认的长连接

总结

TCP半关闭提供了比close更精细的连接控制能力:

  1. 更优雅的结束方式:明确传达结束意图
  2. 更高效的资源利用:避免不必要的等待
  3. 更灵活的协议设计:支持复杂交互模式

掌握半关闭技术,能让你的网络程序像优秀的电话沟通一样:知道何时该说,何时该听,何时可以礼貌地结束对话。这种精准控制正是高级网络编程的重要技能之一。
制能力:

  1. 更优雅的结束方式:明确传达结束意图
  2. 更高效的资源利用:避免不必要的等待
  3. 更灵活的协议设计:支持复杂交互模式

掌握半关闭技术,能让你的网络程序像优秀的电话沟通一样:知道何时该说,何时该听,何时可以礼貌地结束对话。这种精准控制正是高级网络编程的重要技能之一。

http://www.lryc.cn/news/587818.html

相关文章:

  • 使用layui的前端框架过程中,无法加载css和js怎么办?
  • 如何通过添加企业logo视频水印来对教育视频进行加密?
  • 8:从USB摄像头把声音拿出来--ALSA大佬登场!
  • GNhao,长期使用跨境手机SIM卡成为新趋势!
  • 控制台打开mysql服务报错解决办法
  • 我的Qt八股文面试笔记1:信号与槽文件流操作
  • Sharding-Sphere学习专题(四)广播表和绑定表、分片审计
  • 胡志明证券交易所新一代交易系统解决方案——基于美联储利率决议背景下的越南跨境金融基础设施升
  • 学习C++、QT---25(QT中实现QCombobox库的介绍和用QCombobox设置编码和使用编码的讲解)
  • 2025js——面试题(8)-http
  • 第二章 基于新版Onenet搭建云服务(stm32物联网)
  • 【leetcode】326. 3的幂
  • 对偶原理与蕴含定理
  • SSE(Server-Sent Events)和 MQTT(Message Queuing Telemetry Transport)
  • 【工具】AndroidStudio修改中文语言汉化
  • 【2025/07/14】GitHub 今日热门项目
  • 直播推流技术底层逻辑详解与私有化实现方案-以rmtp rtc hls为例-优雅草卓伊凡
  • QML 常用控件(二)
  • vue中配置Eslint的步骤
  • Why C# and .NET are still relevant in 2025
  • lightgbm算法学习
  • Python----NLP自然语言处理(中文分词器--jieba分词器)
  • 《大数据技术原理与应用》实验报告一 熟悉常用的Linux操作和Hadoop操作
  • .NET控制台应用程序中防止程序立即退出
  • 2025年大数据、建模与智能计算国际会议(ICBDMIC 2025)
  • spring-ai-alibaba 接入Tushare查询股票行情
  • 【C++进阶】---- 多态
  • SpringBoot3整合“Spring Security+JWT”快速实现demo示例与Apifox测试
  • 鸿蒙开发NDK之---- 如何将ArkTs的类型转化成C++对应的类型(基础类型,包含部分代码解释)
  • 系统化构建产品开发体系