网络编程:服务器监听+非阻塞设置

cpp 复制代码
// 3. 开始监听
    if (listen(listen_sockfd, 10) < 0) {
        perror("listen failed");
        return 1;
    }
    set_non_blocking(listen_sockfd); // 将监听套接字也设为非阻塞

逐行超详细解释:监听 + 非阻塞设置

这段代码是**TCP服务器从"准备就绪"变成"正式营业"**的关键一步。

先看整体作用(大白话)

c 复制代码
// 告诉操作系统:我这个服务器准备好接收客户端连接了!
// 并且最多让10个客户端排队等待连接
listen(listen_sockfd, 10);

// 把监听的"电话"设置成非阻塞模式
// 意思是:没人打电话时,我可以去干别的事,不用死等
set_non_blocking(listen_sockfd);

逐行深度拆解

第一行:if (listen(listen_sockfd, 10) < 0) {

1. listen() 函数作用

将套接字从「主动套接字」变为「被动监听套接字」

  • 调用前:这个socket只是一个普通文件
  • 调用后:内核开始监听端口,有客户端来连接就会通知程序

2. 第一个参数:listen_sockfd

  • 就是你之前创建、设置复用、绑定好端口的监听套接字
  • 告诉内核:我要监听这个端口上的连接

3. 第二个参数:10监听队列长度 / 等待连接数

这是高频面试题 + 核心知识点

  • 含义:内核中允许排队等待被 accept 的最大客户端连接数
  • 简单理解:"候客区"容量
    • 候客区满了 → 新客户端会连接失败/被拒绝
  • 通常写:5 ~ 128(不要太大也不要太小)

注意:实际内核队列大小会比你填的略大(系统会自动调整),但我们填10就代表最多让10个连接排队。

4. < 0 与错误判断

  • listen() 成功 → 返回 0
  • listen() 失败 → 返回 -1
  • 失败原因:
    • 没调用 bind() 就直接监听
    • 文件描述符非法
    • 端口未绑定

第二行、第三行:perror("listen failed"); return 1;

1. perror("listen failed");

  • 打印系统级错误原因

  • 例子:如果没bind就listen,会打印:

    复制代码
    listen failed: Invalid argument
  • 作用:快速定位bug

2. return 1;

  • 程序异常退出,返回错误码1
  • 服务器监听失败,无法继续运行,直接退出

重点:第四行 set_non_blocking(listen_sockfd);

这行是高性能服务器(非阻塞/IO多路复用)的关键!

1. 什么是阻塞 vs 非阻塞?

【阻塞模式(默认)】
复制代码
没人来连接 → 程序卡住不动,死等
  • 缺点:只能等连接,啥也干不了,无法处理高并发
【非阻塞模式】
复制代码
没人来连接 → 函数立刻返回,不卡住,程序可以去做别的事
  • 优点:配合 select/poll/epoll 实现高并发服务器

2. 这行做了什么?

监听套接字设置为非阻塞模式

  • 以后调用 accept()
    • 有连接 → 正常接收
    • 没连接 → 不卡住,直接返回错误(EAGAIN/EWOULDBLOCK)

3. 为什么要把监听套接字也设为非阻塞?

因为你后面要使用:

  • IO多路复用(select/poll/epoll)
  • 高并发处理
  • 不能让服务器在任何地方被卡住

完整原理流程图(一看就懂)

复制代码
客户端发送连接请求 → 到达服务器端口
↓
内核自动接收连接(TCP三次握手内核完成!)
↓
连接放入「等待队列」(最多放10个)
↓
服务器调用 accept() → 从队列取走连接

listen() 的作用:开启这个内核队列,开始自动接收连接!


极简总结(超好记)

  1. listen():开启监听,让内核帮你自动处理TCP连接
  2. 参数10:内核等待队列长度(候客区最多10人)
  3. 返回值判断:监听失败就报错退出
  4. set_non_blocking :设置非阻塞模式,不卡住程序,支持高并发
  5. 核心意义 :服务器正式开始对外接收客户端连接

一句话总结

listen 让内核帮你排队等连接,非阻塞让你的程序永远不会卡死,这是高性能服务器的标准写法!

相关推荐
学困昇1 小时前
彻底搞懂 Linux 基础 IO:文件描述符、重定向、dup2、缓冲区一次讲透!
linux·运维·服务器·开发语言·c++
赋创小助手1 小时前
PCIe 8.0 要来了:1TB/s 带宽背后,AI 算力服务器正在进入“高速互联时代”
运维·服务器·人工智能
Promise微笑2 小时前
开关柜局放国产替代浪潮下:开关柜局放监测技术与实践深度解析
网络·数据库·人工智能
yyuuuzz2 小时前
国际云服务商运维常见问题梳理
运维·服务器·网络·github·aws
焦糖玛奇朵婷2 小时前
终于搞清楚了,扭蛋机小程序这么厉害❗
java·服务器·前端·程序人生·小程序
量子炒饭大师3 小时前
【Linux系统编程】Cyberpunk在霓虹丛林中构建堡垒 —— 【关于 root 超级管理员权限】
linux·运维·服务器·root·uid
leaves falling3 小时前
Linux基础开发工具详解:从yum到gdb的完整指南
linux·运维·服务器
广然3 小时前
eNSP Pro 实战:华为交换机堆叠,两台变一台
服务器·网络·华为
卡次卡次13 小时前
14.1: 总结本章 Python 高性能并发:多线程+多进程核心知识点+实战指南(面试/开发双适配)
服务器·python·面试