Linux 分析 Socket 中 send/recv 系统调用的阻塞行为

星萱小哥_6732

星萱小哥_6732

2026-07-11

756人浏览

原创

send/recv的阻塞本质是用户空间与内核缓冲区间数据拷贝的等待逻辑:阻塞模式下,send等待缓冲区有足够空间才完成拷贝,recv等待接收缓冲区有数据才开始拷贝;非阻塞模式下二者均立即返回,由调用方处理eagain或循环重试。

linux 分析 socket 中 send/recv 系统调用的阻塞行为

Linux 中 send/recv 的阻塞行为,本质不是“发出去”或“收进来”,而是数据在用户空间与内核缓冲区之间拷贝时的等待逻辑。理解这一点,才能避开常见误区——比如以为 send 返回成功就等于对方收到了数据。

send 在阻塞与非阻塞模式下的关键差异

send 的作用始终是:把应用层 buf 中的数据,尽可能拷贝到内核 TCP 发送缓冲区(sk->sk_write_queue)。它不参与实际网络发送,那是协议栈后续做的事。

  • 阻塞模式下:如果发送缓冲区剩余空间
  • 非阻塞模式下:只要缓冲区有空,就尽最大努力拷——可能只拷 1 字节、也可能拷全部;若缓冲区全满,直接返回 -1 并设 errno=EAGAIN/EWOULDBLOCK。不会等,也不保证原子性。
  • 特别注意:即使 send 成功返回,若之后网络断开或对端 RST,下一次 socket 调用(如 send 或 recv)才可能暴露错误;TCP 不会在 send 时校验链路连通性。

recv 的阻塞逻辑取决于接收缓冲区状态

recv 的任务是:把内核 TCP 接收缓冲区(sk->sk_receive_queue)里的数据,拷贝到用户提供的 buf 中。是否阻塞,只看这个缓冲区此刻有没有可用数据。

Linux Ai Server
Linux Ai Server

Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。

下载
  • 阻塞模式下:若接收缓冲区为空,进程挂起休眠,直到有数据到达(含 FIN)或连接异常(如对端关闭、超时)。一旦有数据,哪怕只有 1 字节,也会立即拷贝并返回实际字节数;不会等到 buf 满才返回。
  • 非阻塞模式下:缓冲区空则立刻返回 -1 + errno=EAGAIN/EWOULDBLOCK;有数据则拷贝 min(len, 可用字节数),返回实际拷贝量。调用方需自行循环重试或结合事件驱动机制处理。
  • recv 返回 0 表示对端已正常关闭连接(FIN 到达且本端已读完所有数据),这不是错误,是连接终止的明确信号。

影响阻塞行为的底层参数与配置

阻塞与否由 socket 文件描述符的标志位决定,但实际表现还受内核缓冲区大小和协议栈状态制约:

  • 发送缓冲区大小可通过 setsockopt 设置 SO_SNDBUF,但受 net.core.wmem_max 限制;过小会导致阻塞更频繁,过大则增加内存占用和延迟。
  • 接收缓冲区大小对应 SO_RCVBUF,同样受 net.core.rmem_max 约束;若应用 recv 不及时,缓冲区满后对端将受 TCP 流量控制限制(窗口为 0),进而影响 send 行为。
  • 默认创建的 socket 是阻塞的;设为非阻塞需显式调用 fcntl(sockfd, F_SETFL, O_NONBLOCK) 或创建时指定 SOCK_NONBLOCK。
  • UDP socket 的 send/recv 不涉及可靠传输队列,因此 sendto/recvfrom 在阻塞模式下也几乎不阻塞(除非系统资源耗尽),这点与 TCP 有本质区别。

如何判断当前是否该用阻塞还是非阻塞

选择依据不是“习惯”,而是服务模型和性能目标:

  • 单连接、交互简单(如 CLI 工具、短连接 HTTP 客户端):阻塞模式代码简洁,无需轮询或事件循环。
  • 高并发服务器(如 Web 服务、IM 后端):必须用非阻塞 + I/O 多路复用(epoll/select);否则每个连接都占一个线程/进程,资源消耗不可控。
  • 需要精确控制超时(如金融报文、心跳检测):非阻塞配合 epoll_wait 或 setsockopt(SO_RCVTIMEO/SO_SNDTIMEO) 更可靠;阻塞模式下仅靠 alarm() 难以精准干预 socket 调用。
  • 流式大文件传输:可混合使用——用阻塞 recv 避免忙等,但需搭配 SO_RCVLOWAT 控制最小触发阈值,减少系统调用次数。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

linux

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
服务器是什么
服务器是什么

服务器是一种计算机硬件设备或软件程序,它具有强大的计算和存储能力,用请求、存储数据和提供服务。它在互联网中着关重要的作用,为用户提供各种服务和资源。本专题为大家提供服务器相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.15

457

5

连接apple id服务器时出错
连接apple id服务器时出错

连接apple id服务器时出错的原因包括网络连接问题、服务器问题、Apple ID账户问题、设备问题、防火墙或安全软件问题、时间和日期设置问题、Apple服务器维护等。本专题为大家提供apple id相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.08

940

5

搭建互联网服务器
搭建互联网服务器

搭建互联网服务器需要:1、选择合适的硬件和操作系统,第一步是选择合适的硬件和操作系统;2、安装和配置操作系统,是搭建互联网服务器的关键步骤;3、安装和配置服务器软件,是搭建互联网服务器的下一步,常见的服务器软件包括Apache、Nginx、Tomcat等;4、配置防火墙和安全性,是搭建互联网服务器的重要步骤;5、域名解析和配置,是搭建互联网服务器的最后一步。

2023.09.19

2992

5

如何查看服务器状态
如何查看服务器状态

查看服务器状态的方法有使用命令行工具、图形界面工具、监控工具、日志文件和远程管理工具等。本专题为大家提供服务器状态相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.09

996

5

服务器域名转接慢怎么解决
服务器域名转接慢怎么解决

服务器域名转接慢的解决办法有DNS优化、服务器优化、CDN加速、前端优化和网络优化等。本专题为大家提供服务器相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.17

889

5

服务器评测软件
服务器评测软件

服务器评测软件有PassMark Software、CPU-Z、GPU-Z、CrystalDiskMark、IOmeter、JMeter、LoadRunner、Apache Bench等等。详细介绍:1、PassMark Software是一款综合性的服务器性能测试软件,可以评估服务器在各种负载条件下的性能;2、CPU-Z是一款可以提供服务器CPU详细信息的软件等等。

2023.10.17

454

3

如何开启TFTP服务器
如何开启TFTP服务器

开启TFTP服务器的步骤包括选择TFTP服务器软件、下载和安装软件、配置TFTP服务器以及启动和测试服务器等。本专题为大家提供服务器相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

2736

4

服务器负载不兼容怎么解决
服务器负载不兼容怎么解决

解决方法:1、增加服务器资源;2、负载均衡;3、优化应用程序;4、增加缓存机制;5、分布式架构;6、限流和熔断;7、自动化扩容。想知道更详细服务器负载不兼容的解决方法,可以访问本专题下面的文章。

2023.10.20

5092

4

宽带如何接入服务器
宽带如何接入服务器

宽带接入服务器的方法有ADSL宽带接入服务器、光纤接入服务器、无线接入服务器和以太网接入服务器等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.20

807

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习