Linux:基于TCP Socket的在线翻译

在学习网络编程的过程中,TCP 是绕不开的核心。本篇博客将结合一个**"英译中小词典服务器"项目**,带你从代码角度理解 TCP 编程的基本流程与设计思路(与之前的Udp是差不多的哦,我们主要学习的思路)


一、项目功能概述

我们实现了一个简单的客户端-服务器模型:

  • 客户端:输入英文单词

  • 服务器:查询本地字典并返回中文翻译

  • 通信协议:基于 TCP

例如:

复制代码
客户端输入: apple
服务器返回: 苹果

二、TCP 编程核心流程

1️⃣ 服务端流程

服务端主要分为以下几步:

复制代码
socket -> bind -> listen -> accept -> read/write

对应代码逻辑:

(1)创建 socket

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

  • SOCK_STREAM:TCP协议


(2)绑定端口

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

作用:让服务器在某个端口"对外提供服务"。


(3)开始监听

复制代码
listen(_listenSockfd, backlog);
  • backlog 表示等待队列长度

(4)获取连接(关键点)

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

特点:

  • 阻塞函数

  • 没有客户端连接时会一直等待


(5)通信处理

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

三、客户端流程

客户端相对简单:

复制代码
socket -> connect -> read/write

(1)创建 socket

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

(2)连接服务器

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

(3)发送与接收数据

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

四、模块设计亮点(重点!)

这个项目不仅仅是"能跑",还有几个非常好的设计思想👇


⭐ 1. 解耦设计(函数回调)

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

服务器并不关心"业务逻辑",而是通过回调:

复制代码
std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(
    port,
    [&](const std::string& word, InetAddr& cilent){
        return d.Translate(word, cilent);
    }
);

👉 好处:

  • 可以轻松替换为:

    • 聊天服务器

    • 计算服务

    • 命令执行服务


⭐ 2. 字典模块(Dict)

复制代码
_dict[english] = chinese;

支持格式:

复制代码
apple:苹果
banana:香蕉

查找逻辑:

复制代码
if (_dict.find(word) == _dict.end())
    return "None";

⭐ 3. 封装网络地址(InetAddr)

统一处理:

  • 主机序 → 网络序

  • IP / Port 提取

  • sockaddr 转换

例如:

复制代码
InetAddr addr(peer);
addr.Ip();
addr.Port();

👉 避免重复写底层代码


⭐ 4. 多线程并发处理

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

每个客户端一个线程:

复制代码
客户端1 ------线程1
客户端2 ------线程2
客户端3 ------线程3

👉 提高并发能力


⭐ 5. 禁止拷贝(工程规范)

复制代码
class NoCopy
{
    NoCopy(const NoCopy&) = delete;
};

用于防止:

  • socket 被误拷贝

  • 资源重复释放


五、三种并发模型对比

1️⃣ 单进程(最简单)

复制代码
Service(sockfd, addr);
  • ❌ 阻塞

  • ❌ 无法并发


2️⃣ 多进程

复制代码
fork();
  • ✅ 稳定

  • ❌ 开销大


3️⃣ 多线程

复制代码
pthread_create(...)
  • ✅ 性能好

  • ✅ 常用方案


六、一个容易忽略的细节(我们之后会解决,这里只是学习代码)

❗ read / write 并不保证完整读写

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

问题:

  • TCP 是流式协议

  • 可能出现:

    • 粘包

    • 半包

👉 工业级方案需要:

  • 自定义协议(长度 + 数据)

  • 或使用分隔符

源代码很多,所以这里就不给啦,详细的可以查看我的gitee目录哦

class_26_3_20/dictionary.txt · 小沐/linux_network - 码云 - 开源中国

相关推荐
姜鱼问生3 小时前
Nginx 缓存命中率监控:从 X-Cache-Status 到实时统计
运维·nginx·缓存
Apipi*4 小时前
30天速通Linux 第六章信号及信号处理
linux·运维·信号处理
不像程序员的程序媛4 小时前
检测网络的命令mtr详解
网络
敬往事一杯酒哈4 小时前
海康 AGV 导航读码器学习
学习
天启HTTP5 小时前
爬虫防封核心原理:IP轮换机制与风控规避逻辑
linux·服务器·网络·爬虫·tcp/ip
运维行者_5 小时前
网络性能监控怎么做?从自动发现到根因分析的4个环节
运维·服务器·网络·人工智能·支持向量机
此时不提桶,更待何时5 小时前
06-14-A-Kafka集群运维与迁移实战详解
运维·kafka
qq_284274056 小时前
机械原理笔记:平面机构自由度计算(复合铰链、局部自由度、虚约束)与四杆机构入门(含考点)
笔记·学习·平面·自动化·制造
hz567897 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC7 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库