ConnVerifier is a Go TCP keepalive stress tool used to verify whether long-lived TCP sessions remain stable after passing through NAT.
server.go— Minimal echo server. It listens on a configurable TCP port, accepts connections, and echoes back every byte it receives.client.go— Concurrent connection generator. It maintains many TCP sessions, sends periodic heartbeats, retries with exponential backoff, and prints per-second stats.
go build server.go
go build client.goEach file has its own main, so they must be built separately.
-
Start the server:
./server -addr :9000
-
Start the client:
./client \ -addr <server-ip>:9000 \ -clients 10000 \ -start-rate 500 \ -heartbeat 30s \ -dial-timeout 5s \ -io-timeout 5s \ -min-backoff 500ms \ -max-backoff 1m
| Flag | Default | Description |
|---|---|---|
-addr |
127.0.0.1:9000 |
Target server address |
-clients |
1000 |
Target number of concurrent connections |
-start-rate |
100 |
Max new connections started per second |
-heartbeat |
30s |
Heartbeat interval |
-dial-timeout |
5s |
TCP dial timeout |
-io-timeout |
5s |
Deadline for heartbeat write/read |
-min-backoff |
500ms |
Initial reconnect backoff |
-max-backoff |
1m |
Maximum reconnect backoff |
The client prints one stats line per second:
stats target=1000 active=998 connected=1000 drops=12 heartbeats=42 ack=42 dials=3 reconnects=12
| Field | Description |
|---|---|
target |
Configured target connection count |
active |
Currently active connections |
connected |
Total successful dial count since startup |
drops |
Total connections that dropped and entered reconnect flow |
heartbeats |
Total heartbeat writes sent |
ack |
Total heartbeat responses successfully read |
dials |
Total dial failures |
reconnects |
Total reconnect attempts scheduled after dropouts |
server.golistens forSIGINT/SIGTERM, closes the listener, waits for active goroutines, then printsserver stopped.client.golistens forSIGINT/SIGTERM, printsshutting down..., waits 5 seconds for in-flight cleanup, then exits.
- Raise
ulimit -nbefore starting the client so the OS allows enough file descriptors. - No external dependencies — uses only the Go standard library.
ConnVerifier 是一个 Go 版 TCP Keepalive 压测工具,用于验证经过 NAT 之后的 TCP 长连接是否能够稳定维持。
server.go— 最小回声服务,监听可配置端口,接受连接后将收到的字节原样回写。client.go— 并发连接器,负责维持大量 TCP 会话、定期发送心跳、指数退避重连,并输出每秒统计信息。
go build server.go
go build client.go两个文件都包含 main,需要分别编译。
-
启动服务端:
./server -addr :9000
-
启动客户端:
./client \ -addr <server-ip>:9000 \ -clients 10000 \ -start-rate 500 \ -heartbeat 30s \ -dial-timeout 5s \ -io-timeout 5s \ -min-backoff 500ms \ -max-backoff 1m
| 参数 | 默认值 | 说明 |
|---|---|---|
-addr |
127.0.0.1:9000 |
目标服务器地址 |
-clients |
1000 |
目标并发连接数 |
-start-rate |
100 |
每秒最大新连接数 |
-heartbeat |
30s |
心跳间隔 |
-dial-timeout |
5s |
TCP 拨号超时 |
-io-timeout |
5s |
心跳读写超时 |
-min-backoff |
500ms |
初始重连退避 |
-max-backoff |
1m |
最大重连退避 |
客户端每秒输出一行统计信息:
stats target=1000 active=998 connected=1000 drops=12 heartbeats=42 ack=42 dials=3 reconnects=12
| 字段 | 说明 |
|---|---|
target |
配置的目标连接数 |
active |
当前活跃连接数 |
connected |
启动以来累计成功拨号数 |
drops |
累计掉线次数 |
heartbeats |
累计心跳发送数 |
ack |
累计心跳确认数 |
dials |
累计拨号失败数 |
reconnects |
累计重连尝试次数 |
server.go监听SIGINT/SIGTERM,关闭监听器后等待活跃 goroutine 退出,打印server stopped。client.go监听SIGINT/SIGTERM,打印shutting down...,等待 5 秒收尾后退出。
- 运行前请提升
ulimit -n,确保文件描述符数量足够。 - 无外部依赖,仅使用 Go 标准库。