TCP 网络编程学习笔记

一、常见踩坑点

现象 原因 解决方法
编译时 undefined reference to ... 未链接必要的库(如 -lts 对于 tslib,但 TCP 编程无需额外库) TCP 编程一般只需 gcc 直接编译,若使用 pthread 等需加 -lpthread
运行客户端时提示 Usage: ./client <server_ip> 未提供 IP 地址参数 运行:./client 127.0.0.1
服务器 bind error: Address already in use 端口被占用,可能是上一个服务器进程未退出,或处于 TIME_WAIT 状态 1. 用 pkill server 杀掉旧进程 2. 使用 setsockopt 设置 SO_REUSEADDR 选项
客户端 connect error 服务器未运行,或 IP 地址错误,或防火墙阻止 确保服务器已启动,IP 正确,尝试 ping 测试连通性
服务器子进程变成僵尸(<defunct> 父进程未回收子进程资源 在服务器开头添加 signal(SIGCHLD, SIG_IGN); 让系统自动回收
客户端输入 exit 后服务器没反应 客户端发送的字符串包含换行符 \n,而服务器用 strcmp 比较时未去除 在客户端用 strcspn 或手动去掉换行符;或在服务器接收后也去掉换行符
服务器打印乱码或额外字符 接收到的数据未以 \0 结尾,直接打印 recv 后加上 ucRecvBuf[iRecvLen] = '\0';
第二个客户端无法连接/通信 服务器未使用并发(fork/线程),主进程阻塞在第一个客户端的 recv 使用 fork 创建子进程处理每个客户端,或用 select/poll 实现 I/O 多路复用
客户端正常退出,但服务器端 recv 未返回 0 客户端未正确关闭 socket(如只 exit 未调用 close 在客户端 break 前调用 close(iSocketClient);
服务器端打印的客户端编号始终是 0 或 -1 忘记在每次 accept 后递增 iClientNum,或未正确传递 accept 成功后 iClientNum++,子进程中应使用该编号(注意子进程复制了父进程变量)

二、核心概念总结

1. TCP 编程基本步骤

服务器端

  1. socket() -- 创建监听 socket

  2. bind() -- 绑定 IP 和端口

  3. listen() -- 开始监听

  4. accept() -- 等待客户端连接,返回新的通信 socket

  5. recv() / send() -- 与客户端通信

  6. close() -- 关闭 socket

客户端

  1. socket() -- 创建 socket

  2. connect() -- 连接服务器

  3. send() / recv() -- 通信

  4. close() -- 关闭

2. 并发处理

  • 使用 fork() 为每个客户端创建一个子进程,父进程继续等待新连接。

  • 子进程处理完通信后必须退出(returnexit),避免成为僵尸。

  • 使用 signal(SIGCHLD, SIG_IGN) 让系统自动回收子进程资源,避免僵尸进程。

3. 优雅关闭连接

  • 应用层可以约定特殊命令(如 exit)作为断开信号。

  • 发送 exit 后,客户端主动关闭 socket。

  • 服务器端收到 exitrecv 返回 0,也应关闭 socket 并退出子进程。

4. 字符串协议注意事项

  • 网络传输的是字节流,没有自动的字符串结束符。

  • 接收后必须手动添加 \0 才能作为 C 字符串处理。

  • 使用 fgets 时会保留换行符,需去除后再比较(或用 strncmp 指定长度)。

5. 阻塞 I/O 的影响

  • 默认情况下,acceptrecvsend 等函数会阻塞直到操作完成。

  • 单进程服务器如果阻塞在一个客户端的 recv 上,将无法接受新连接或处理其他客户端。

  • 解决方案:多进程、多线程、非阻塞 I/O、I/O 多路复用(select/poll/epoll)。


三、学习收获

通过本次学习,你掌握了:

  • TCP 套接字编程的核心函数和流程。

  • 如何使用 fork 实现简单的并发服务器。

  • 如何自定义应用层协议(如退出命令)实现优雅关闭。

  • 常见错误的排查方法(端口占用、僵尸进程、字符串处理等)。

  • 通过修改代码、观察现象加深了对阻塞、并发等概念的理解。

这些知识是后续学习更高级网络编程(如 epoll、多线程、异步 I/O)的基础,也是开发实际网络应用(聊天室、文件传输、远程控制等)的必备技能。

相关推荐
3D探路人30 分钟前
模灵 大模型聚合API 转发流程技术实现
java·大数据·开发语言·前端·人工智能·计算机视觉
l1t1 小时前
JIT执行python脚本的工具codon安装和测试
开发语言·python
TO_WebNow1 小时前
使用thinkPHP8.x 访问接口提示跨域
前端·php
程似锦吖1 小时前
无中生有 之 从0开始写一个动态定时任务管理
java·开发语言
Dxy12393102162 小时前
Python 去除 HTML 标签获取纯文本
开发语言·python·html
洛的地理研学2 小时前
Python下载并处理MOD13A3植被指数数据
开发语言·python
humcomm2 小时前
Java 新特性2026年5月速览
java·开发语言
xiao_li_ya2 小时前
C++学习日记1(`*`的理解、const关键词)
开发语言·c++
码力斜杠哥2 小时前
Rust初习录(6)Rust的 if 玩法
开发语言·python·rust
聆风吟º2 小时前
【C标准库】深入理解C语言 isalpha 函数详解:判断字符是否为字母
c语言·开发语言·库函数·isalpha