《TCP/IP 网络编程》学习记录
简要记录我的《TCP/IP 网络编程》学习过程。
《TCP/IP 网络编程》学习记录
Chapter 1
Section 1.1
run hello_server.c
run hello_client.c
Section 1.2
run low_open.c
run low_read.c
run fd_seri.c
Chapter 2
Section 2.1
run tcp_server.c
run tcp_client.c
Chapter 3
Section 3.3
Section 3.4
run inet_addr.c
run inet_aton.c
run inet_ntoa.c
Chapter 4
Section 4.3
run echo_server.c
run echo_client.c 1
run echo_client.c 2
run echo_client.c 3
Chapter 5
Section 5.1
run op_server.c
run op_client.c
Error
bind() error
问题描述
短时间内连续两次运行 ./hserver 9190 会报错 bind() error
bind() error
问题原因
之前运行过服务器,TCP 端口需要一段时间才能完全释放。等待1-2分钟再重试既可。这是典型的 TCP 端口 TIME_WAIT 状态 问题。
当关闭服务器程序后,TCP 套接字会进入 TIME_WAIT 状态,通常持续 1-2 分钟。在这个状态下:
- 操作系统保留端口号,确保网络中所有数据包都已完成传输
- 相同的 IP:端口组合暂时无法立即重用
解决方案
方法1:设置 SO_REUSEADDR 套接字选项
在 bind() 之前添加:
1
2
3
// 在 socket() 之后,bind() 之前添加:
int optval = 1;
setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
完整代码示例:
1
2
3
4
5
6
7
8
9
10
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock == -1)
error_handling("socket() error");
// 添加这3行:允许地址重用
int optval = 1;
setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
memset(&serv_addr, 0, sizeof(serv_addr));
// ... 其余代码不变
方法2:等待 TIME_WAIT 超时
等待 1-2 分钟端口自动释放。
方法3:使用不同的端口号
1
2
./hserver 9191
./hserver 9192
验证
Note
SOCK_STREAM 与 SOCK_DGRAM
| 对比项 | SOCK_STREAM | SOCK_DGRAM |
|---|---|---|
| 协议 | TCP(传输控制协议) | UDP(用户数据报协议) |
| 连接方式 | 面向连接(需建立连接) | 无连接(无需建立连接) |
| 传输方式 | 字节流(数据连续、无边界) | 数据报(以独立数据包发送) |
| 可靠性 | 可靠,保证顺序、无丢包 | 不可靠,可能丢包、乱序 |
| 传输速度 | 较慢(因确认与重传机制) | 较快(无握手、无重传) |
| 适用场景 | 文件传输、HTTP、远程登录等 | 实时音视频、广播、DNS 查询等 |
This post is licensed under CC BY 4.0 by the author.

