LINUX ---网络编程(三)

发布于:2025-09-01 ⋅ 阅读:(16) ⋅ 点赞:(0)

1.单客户端服务器

工作流程:socket 创建→bind 绑定→listen 监听→accept 建立单个连接→循环读写通信;
特点:一次只能处理一个客户端连接,处理完才能接受新连接;
局限性:无法同时服务多个客户端,仅适用于简单测试场景;

2.单循环多客户端服务器

工作流程:在主循环中重复执行 accept 接受连接→与客户端通信→关闭连接的过程;
特点:能处理多个客户端,但需串行处理(必须等上一个客户端断开才能处理下一个);
局限性:效率低,不支持真正的并发,适合客户端交互简单且连接数极少的场景;

3.多进程多客户端服务器

工作流程:主进程负责 accept 接受连接,通过 fork 创建子进程专门处理每个客户端的通信。
特点
        支持真正的并发处理,多个客户端可同时交互;
        父进程持续接受新连接,子进程独立处理对应客户端;
        需要处理僵尸进程问题(通过信号机制回收);
局限性:进程创建和切换开销较大,不适合高并发场景;

核心差异:并发能力的实现方式不同,从完全不支持并发(单客户端)→串行处理(单循环)→并行处理(多进程),逐步提升了服务器的服务能力,但也带来了更复杂的实现和更多的系统资源消耗。
实际开发中,还会根据需求选择多线程模型(线程开销小于进程)或 IO 多路复用模型(如 epoll,单进程高效处理多连接)等更优方案。

1. 地址重用(SO_REUSEADDR)

作用:解决服务器重启时因端口处于 TIME_WAIT 状态导致的 "地址已被使用" 错误,允许端口快速重新绑定。
实现方式:通过setsockopt函数设置,通常在socket()创建后、bind()之前调用:

int on = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));

参数意义:
SOL_SOCKET:在 socket 层设置选项;
SO_REUSEADDR:开启地址重用功能的选项名;
&on:传入非 0 值表示启用该功能;

2. 多线程多客户端服务器模型

核心思想:主进程负责接受客户端连接,为每个连接创建独立线程处理通信,实现并发服务。
工作流程:
        主流程:socket()创建监听套接字 → 设置地址重用 → bind()绑定 → listen()监听 → 循环accept()接受连接。
        连接处理:每接受一个连接,通过pthread_create()创建线程,由线程执行do_client函数处理具体通信。
        线程函数:循环read()接收数据 → 处理(如sprintf拼接响应)→ write()发送响应,直到客户端断开。
关键细节:
        使用pthread_detach()设置线程分离属性,自动回收线程资源,避免僵尸线程。
        连接描述符connfd需动态分配(如malloc),避免多线程共享同一地址导致的冲突。
        线程结束前需释放资源(如free动态分配的内存)并关闭连接。
优势:
        线程创建 / 销毁开销远小于进程,资源占用更低。
        适合处理 IO密集型任务(如网络通信),并发效率高于多进程模型。

特性 多进程模型 多线程模型
资源开销 大(独立内存空间) 小(共享进程资源
上下文切换     快
通信复杂度 高(需 IPC 机制)     低(可直接共享内存)
稳定性 高(进程隔离) 低(线程崩溃影响整体)
适用场景 计算密集型任务      网络通信等IO 密集型任务