Linux:基于TCP Socket的客户端-服务器实现的远程命令行项目

本文将基于一个完整的项目代码,系统讲解如何使用 C++ 实现一个 TCP 客户端与服务器,并重点说明实现过程中所涉及的核心知识点


一、项目整体结构

本项目采用典型的 客户端 - 服务器模型

  • 客户端:负责连接服务器、发送请求、接收响应

  • 服务器:负责监听连接、处理请求、返回结果

核心模块包括:

复制代码
InetAddr      ------ 网络地址封装
TcpServer     ------ TCP服务器框架
Command       ------ 业务处理逻辑
Client        ------ 客户端程序

二、TCP 编程基础知识

在实现之前,需要掌握以下基础知识:


1. Socket 编程模型

TCP 通信基于 socket,基本流程如下:

服务端流程

复制代码
socket → bind → listen → accept → read/write

客户端流程

复制代码
socket → connect → read/write

2. 网络字节序

网络传输统一使用 大端字节序,因此需要:

  • htons:主机序 → 网络序(端口)

  • ntohs:网络序 → 主机序

  • inet_pton:字符串 IP → 二进制

  • inet_ntop:二进制 → 字符串 IP


3. sockaddr 结构

TCP 使用:

复制代码
struct sockaddr_in

但接口统一使用:

复制代码
struct sockaddr*

因此需要进行类型转换。


三、InetAddr:网络地址封装

为了避免重复操作底层结构,本项目封装了 InetAddr 类。


1. 功能

  • 封装 IP + Port

  • 提供网络序与主机序转换

  • 提供接口给 socket 使用


2. 构造方式

(1)从网络结构构造(服务端 accept)

复制代码
InetAddr(const sockaddr_in &addr)

作用:

  • 提取 IP

  • 转换端口为主机序


(2)客户端构造

复制代码
InetAddr(const std::string& ip, uint16_t port)

作用:

  • 构造用于 connect 的地址结构

(3)服务端构造

复制代码
InetAddr(uint16_t port)

特点:

  • IP 设置为 INADDR_ANY

  • 监听所有网卡


3. 核心接口

复制代码
const struct sockaddr* NetAddrPtr();
const size_t NetAddrLen();

👉 用于 socket API 调用


四、客户端实现

客户端逻辑较为简单,核心代码如下:


1. 创建 socket

复制代码
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  • SOCK_STREAM 表示 TCP

2. 连接服务器

复制代码
connect(sockfd, cilent.NetAddrPtr(), cilent.NetAddrLen());

3. 数据通信

复制代码
write(sockfd, line.c_str(), line.size());
read(sockfd, buffer, sizeof(buffer));

流程:

  1. 从标准输入读取数据

  2. 发送给服务器

  3. 接收服务器返回结果

  4. 输出到终端


4. 关闭连接

复制代码
close(sockfd);

五、TcpServer:服务器实现

服务器是整个项目的核心。


1. 成员变量

复制代码
uint16_t _port;
int _listenSockfd;
bool _isrunning;
func_t _func;

其中:

复制代码
using func_t = std::function<std::string(const std::string&, InetAddr&)>;

👉 表示业务处理函数


2. 初始化(Init)

(1)创建 socket

复制代码
_listenSockfd = socket(AF_INET, SOCK_STREAM, 0);

(2)绑定端口

复制代码
InetAddr local(_port);
bind(_listenSockfd, local.NetAddrPtr(), local.NetAddrLen());

(3)监听

复制代码
listen(_listenSockfd, backlog);

3. 获取连接(accept)

复制代码
int sockfd = accept(_listenSockfd, CONV(peer), &len);

特点:

  • 阻塞等待客户端连接

  • 返回新的通信 socket


4. 请求处理(Service)

复制代码
ssize_t n = read(sockfd, buffer, sizeof(buffer));

处理逻辑:

  • 读取客户端数据

  • 调用业务函数 _func

  • 将结果返回给客户端

    std::string result = _func(buffer, cilent);
    write(sockfd, result.c_str(), result.size());


5. 并发处理(多线程)

为了支持多个客户端同时访问,使用 pthread:


线程数据封装

复制代码
class ThreadData
{
    TcpServer* _tsvr;
    int _sockfd;
    InetAddr _addr;
};

线程入口函数

复制代码
static void* Routine(void* args)

流程:

  1. 分离线程 pthread_detach

  2. 执行 Service

  3. 释放资源


创建线程

复制代码
pthread_create(&tid, nullptr, Routine, td);

👉 每个客户端一个线程


六、业务解耦(回调机制)

服务器不直接处理业务逻辑,而是通过回调函数:

复制代码
std::function<std::string(const std::string&, InetAddr&)>

在 main 中绑定:

复制代码
std::bind(&Command::Execute, &cmd, std::placeholders::_1, std::placeholders::_2)

优点

  • 服务器只负责通信

  • 业务逻辑独立

  • 可扩展性强


七、Command 模块(业务层)

该模块负责处理客户端请求:

复制代码
std::string Execute(const std::string& req, InetAddr& client);

功能可以是:

  • 字符串处理

  • 命令执行

  • 数据查询


八、程序运行流程总结


服务端

复制代码
启动 → 初始化socket → 监听端口 → accept连接 → 创建线程 → 处理请求

客户端

复制代码
启动 → 创建socket → connect服务器 → 输入数据 → 接收响应

九、涉及的核心知识总结

实现本项目需要掌握以下知识:


1. C++ 基础

  • 类与对象

  • 构造函数

  • STL(string、function)

  • 智能指针(unique_ptr)


2. Linux 系统编程

  • socket API

  • 文件描述符

  • read / write

  • close


3. 网络编程

  • TCP 协议

  • 三次握手(建立连接)

  • 四次挥手(断开连接)

  • 网络字节序


4. 多线程

  • pthread

  • 线程创建与分离

  • 并发处理模型


5. 设计思想

  • 封装(InetAddr)

  • 解耦(回调函数)

  • 模块化(TcpServer / Command)

通过这个项目,可以完整理解 TCP 编程从底层 API 到结构设计的全过程。相比只调用接口,这种方式更有助于深入理解网络通信机制,以及服务器程序的基本构建方式

这个实现不仅具备基本通信能力,同时具备良好的扩展性,是进一步学习高性能网络编程的重要基础,接下来我们将学习自定义协议,敬请期待啦

相关推荐
Three~stone2 小时前
Cisco Packet Tracer保姆级安装教程【附汉化教程插件】
linux·运维·服务器·网络安全
艾莉丝努力练剑2 小时前
【Linux线程】Linux系统多线程(一):线程概念
java·linux·运维·服务器·开发语言·学习·线程
C语言小火车2 小时前
Linux 操作系统八股文(2026最新完整版)
java·linux·运维
Deitymoon2 小时前
linux——消息队列进程间通信
linux
24zhgjx-fuhao2 小时前
配置多区域OSPF
网络·智能路由器
嵌入式学习菌2 小时前
内网穿透全闭环实操指南
linux·开发语言·php
come112342 小时前
本地 Docker 容器的“网络端点状态异常”,如何快速修复
网络·docker·容器
Yupureki2 小时前
《Linux网络编程》2.Socket编程(UDP/TCP)
linux·服务器·c语言·网络·c++·tcp/ip·udp
北京智和信通2 小时前
面向复杂IT基础设施的运维一体化解决方案
运维·运维平台·网管平台·信创运维·国产化运维