news 2026/5/21 17:53:39

TCP 多客户端与服务器通信程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TCP 多客户端与服务器通信程序

一、项目简介

本项目是一个基于 Linux实现的 TCP 多客户端与服务器通信程序,主要包含:

  • tcp_server:TCP 服务端程序,监听客户端连接,接收客户端数据,维护在线客户端列表。

  • tcp_client:TCP 客户端程序,连接服务端,支持从标准输入发送消息。

  • 自定义应用层协议:每个数据包由 2 字节 payload 长度 和 payload 内容 组成。

  • 可靠性机制:发送超时、重试、心跳检测、客户端自动重连。

  • 多客户端管理:服务端维护客户端链表,可统计并打印当前在线客户端数量。

服务端默认监听端口为 8080,客户端默认连接 服务器ip "127.0.0.1:8080"。

二、目录结构

Tcpserver_project00v1/ ├── Makefile ├── README.md ├── include/ │ ├── common.h # 公共配置、端口、缓冲区、超时和错误码 │ ├── tcp_client_list.h # 服务端客户端链表管理接口 │ ├── tcp_protocol.h # 协议打包和解析接口 │ ├── tcp_reliability.h # keep-alive、超时、重试接口 │ └── tcp_server.h # 服务端启动接口 ├── src/ │ ├── main.c # 服务端入口 │ ├── tcp_server.c # 服务端主循环、连接接入、select 事件处理 │ ├── tcp_client.c # 客户端入口和通信逻辑 │ ├── tcp_client_list.c # 客户端链表增删查和在线列表打印 │ ├── tcp_protocol.c # 协议解析、业务响应、ACK 回复 │ └── tcp_reliability.c # socket keep-alive、超时和重试发送 └── build/ # 编译生成的中间文件

主要模块职责

  • tcp_server.c: 初始化监听 socket,使用 select 处理新连接和客户端数据,检查客户端空闲超时。

  • tcp_client.c: 连接服务端,读取用户输入,发送业务数据和心跳,处理 ACK 和自动重连。

  • tcp_protocol.c: 实现协议打包、拆包、粘包半包处理、业务回复、心跳 ACK 和数据 ACK。

  • tcp_client_list.c: 维护服务端在线客户端链表。

  • tcp_reliability.c: 封装 socket keep-alive、收发超时和发送重试。

  • common.h: 集中管理端口、缓冲区大小、超时、重试次数和错误码。

三、运行环境

项目代码使用 Linux socket API,适合在 Linux 或 ARM Linux 环境运行。

编译依赖:

  • make

  • ARM 交叉编译工具链二选一:

    • arm-linux-gnueabihf-gcc

    • arm-linux-gcc

Makefile 会自动检测可用的 ARM 交叉编译器。如果两个工具链都不存在,执行 make 会报错。

四、编译说明

在项目根目录执行:

make

编译成功后会生成两个arm32位的可执行文件:

tcp_server tcp_client

清理编译产物:

make clean

如果需要在普通 x86 Linux 主机上本地测试,可以临时修改 Makefile 中的 CC 和 CFLAGS,例如使用:

CC = gcc

CFLAGS = -Wall -O2 -I./include

LDFLAGS =

五、使用说明

1. 启动服务端

在一台终端中运行:

./tcp_server

正常启动后会输出类似信息: TCP服务器启动,监听中... 8080

2. 启动客户端

在另一台终端中运行:

./tcp_client

连接成功后会输出:

已连接到服务器 127.0.0.1:8080

之后可以在客户端终端直接输入文本并回车,客户端会把文本发送给服务端。

示例: hello server

客户端发送后,服务端会打印收到的内容,并回复当前在线客户端数量。客户端会显示类似:

Server replied: Received: hello server,当前在线客户端数:1 Server replied: TYPE:DATA_ACK|SEQ:1|BODY:OK

Received DATA_ACK for SEQ:1

3. 退出客户端

客户端输入以下任意命令可主动退出: quit exit

4. 多客户端连接

可以打开多个终端分别运行:

./tcp_client

每有一个客户端接入,服务端会记录客户端的 fd、IP、端口、连接时间,并打印当前在线客户端列表。

客户端发送消息后,服务端回复中会包含当前在线客户端数量。

5. 心跳和自动重连

客户端会定期发送心跳包: TYPE:HEARTBEAT|SEQ:x

服务端收到后回复: TYPE:HEARTBEAT_ACK|SEQ:x|BODY:OK

如果客户端检测到服务端断开,会先进入倒计时检测阶段,期间每秒尝试重连;如果仍未恢复, 则进入最多 5 次的正式重连流程。连续重连失败后,客户端自动退出。

服务端根据客户端最后活跃时间判断空闲连接, 超过 CLIENT_IDLE_TIMEOUT_SEC 后会关闭该客户端连接。

六、协议说明

1. 数据包格式

每个应用层数据包格式为:

| 2 字节 包头 长度 | payload 包内容 |

  • 长度字段使用网络字节序。

  • 最大 payload 长度为 1024 字节。

  • 服务端和客户端都支持处理 TCP 粘包、半包。

2. 业务数据格式

客户端发送普通业务数据时,优先使用: TYPE:DATA|SEQ:序号|BODY:消息内容

服务端收到后会:

  1. 打印消息内容。

  2. 回复普通业务响应: Received: 消息内容,当前在线客户端数:X

  3. 回复数据确认: TYPE:DATA_ACK|SEQ:序号|BODY:OK

如果输入内容过长,客户端会降级为普通 payload 发送,此时服务端仍会回复业务响应, 但客户端不会等待 DATA_ACK。

3. 心跳格式

客户端发送: TYPE:HEARTBEAT|SEQ:序号

服务端回复: TYPE:HEARTBEAT_ACK|SEQ:序号|BODY:OK

七、重要配置

主要配置位于 include/common.h:

#define PORT 8080 #define BACKLOG 5 #define BUFFER_SIZE 2048 #define MAX_PAYLOAD_LEN 1024 #define HEADER_LEN 2 #define RECV_TIMEOUT_SEC 3 #define SEND_TIMEOUT_SEC 3 #define RETRY_MAX 3 #define RETRY_DELAY_SEC 1 #define HEARTBEAT_INTERVAL_SEC 15 #define HEARTBEAT_ACK_TIMEOUT_SEC 3 #define HEARTBEAT_MAX_RETRIES 3 #define CLIENT_IDLE_TIMEOUT_SEC 60

客户端连接服务器地址位于 src/tcp_client.c:

#define SERVER_IP "127.0.0.1" #define SERVER_PORT PORT

如需连接其他服务器,修改 SERVER_IP 后重新编译。

八、测试说明

1. 编译测试

执行: make clean make

预期结果:

  • 编译过程无错误。

  • 项目根目录生成 tcp_server 和 tcp_client。

2. 单客户端通信测试

步骤:

  1. 启动服务端: ./tcp_server

  2. 启动客户端: ./tcp_client

  3. 在客户端输入: hello

预期结果:

  • 服务端打印收到的客户端消息。

  • 客户端收到 Received: hello,当前在线客户端数:1。

  • 客户端收到对应的DATA_ACK

3. 多客户端在线数量测试

步骤:

  1. 保持服务端运行。

  2. 打开多个终端,分别运行 ./tcp_client。

  3. 在任意客户端输入消息。

预期结果:

  • 服务端打印多个客户端的连接信息。

  • 服务端在线客户端列表数量正确。

  • 客户端收到的服务端响应中,当前在线客户端数与实际连接数一致。

4. 客户端主动退出测试

步骤:

  1. 客户端连接服务端后输入: quit 或 exit

预期结果:

  • 客户端程序退出。

  • 服务端检测到客户端断开,并从在线链表中删除该客户端。

  • 服务端输出剩余在线客户端数量。

5. 心跳测试

步骤:

  1. 启动服务端和客户端。

  2. 不输入任何业务消息,等待约 15 秒。

预期结果:

  • 客户端输出发送心跳的日志,例如 Sent heartbeat SEQ:x。

  • 服务端输出收到心跳的日志,例如 Receive HEARTBEAT, seq=x。

  • 客户端收到HEARTBEAT_ACK并清除等待状态。

6. 服务端断开与客户端自动重连测试

步骤:

  1. 启动服务端和客户端。

  2. 停止服务端程序。

  3. 观察客户端输出。

  4. 在客户端退出前重新启动服务端。

预期结果:

  • 客户端检测到服务端断开。

  • 客户端进入倒计时检测或重连流程。

  • 服务端恢复后,客户端能重新连接成功。

7. 数据 ACK 重试测试

步骤:

  1. 启动服务端和客户端。

  2. 客户端发送普通消息。

  3. 观察客户端是否收到 DATA_ACK。

预期结果:

  • 正常情况下客户端收到 DATA_ACK 后清除待确认数据。

  • 如果 DATA_ACK 超时,客户端会按配置重试发送。

  • 超过最大重试次数后,客户端断开连接并进入重连流程。

8. 长数据测试

步骤:

  1. 启动服务端和客户端。

  2. 在客户端输入接近 1024 字节的字符串。

预期结果:

  • 未超过 MAX_PAYLOAD_LEN 时,数据可被发送。

  • 如果超过 TYPE:DATA|SEQ:x|BODY: 格式可承载长度,客户端会降级为普通 payload 发送。

  • 超过 MAX_PAYLOAD_LEN 时,客户端提示输入过长并拒绝发送。

9. 空闲超时测试

步骤:

  1. 启动服务端。

  2. 使用客户端连接服务端。

  3. 停止客户端心跳或模拟客户端无数据发送。

  4. 等待超过 CLIENT_IDLE_TIMEOUT_SEC。

预期结果:

  • 服务端关闭空闲超时的客户端连接。

  • 服务端从在线客户端链表中删除该客户端。

九、常见问题

1. make 报错找不到交叉编译器

说明当前环境没有安装 arm-linux-gnueabihf-gcc 或 arm-linux-gcc。

解决方式:

  • 在 ARM 交叉编译环境中安装对应工具链。

  • 或修改 Makefile,使用本机 gcc 进行本地测试。

2. 客户端连接失败

检查:

  • 服务端是否已经启动。

  • 服务端端口是否为 8080。

  • 客户端 SERVER_IP 是否指向正确地址。

  • 防火墙是否阻止了端口访问。

3. bind 失败

如果服务端启动时报 bind 错误,可能是 8080 端口已被占用。 可处理方式:

  • 关闭占用该端口的程序。

  • 修改 include/common.h 中的 PORT 后重新编译。

程序下载地址

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 17:46:03

Sunshine游戏串流:5分钟搭建你的私人云游戏服务器终极指南

Sunshine游戏串流:5分钟搭建你的私人云游戏服务器终极指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款开源免费的自托管游戏串流服务器,…

作者头像 李华
网站建设 2026/5/21 17:46:03

终极英雄联盟工具箱:LeagueAkari让你的游戏体验提升300%

终极英雄联盟工具箱:LeagueAkari让你的游戏体验提升300% 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 想象一下,每次…

作者头像 李华
网站建设 2026/5/21 17:44:32

OBS多平台直播插件:obs-multi-rtmp终极配置指南

OBS多平台直播插件:obs-multi-rtmp终极配置指南 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 你是否曾经为同时在不同平台直播而烦恼?需要为每个平台单独配置O…

作者头像 李华
网站建设 2026/5/21 17:44:31

DS4Windows:3个步骤让PS手柄在Windows上获得原生级体验

DS4Windows:3个步骤让PS手柄在Windows上获得原生级体验 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 你是否曾经遇到过这样的情况:在PC上玩游戏时,希…

作者头像 李华