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

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

相关推荐
大树881 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
小宇宙Zz1 天前
Maven依赖冲突
java·服务器·maven
网络研究院1 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智1 天前
ARP代理--工作原理
运维·网络·arp·arp代理
treesforest1 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
shushangyun_1 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
古城小栈1 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
2601_961845151 天前
粉笔行测题库|系统班|刷题
网络·百度·微信·微信公众平台·facebook·新浪微博
程序猿阿伟1 天前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome
凡人叶枫1 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++