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 - 码云 - 开源中国

相关推荐
虹科网络安全5 小时前
解读CRA横向标准EN 40000系列:从法规文本到工程落地 | CRA合规之路(七)
网络·安全·web安全
huainingning6 小时前
华三防火墙web界面ipsec配置
网络
世人万千丶6 小时前
鸿蒙日志体系高级应用:HiLog分级输出/隐私脱敏/远程日志采集/线上问题精准溯源方案
学习·harmonyos·鸿蒙
DLYSB_7 小时前
存储运维实战:基于 Ceph Event 监听与 Python 适配器的分布式存储健康度物理声光响应架构
运维·ceph·python·报警灯
爱丶狸8 小时前
Grafana_Zabbix_ImageRenderer_部署与前端操作手册
linux·前端·zabbix·grafana·kylin
阿里云云原生9 小时前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能
k4m7v2pz9 小时前
把 Bevy 0.14 游戏移植到 R36S 掌机:一场与“无窗口系统“的搏斗
linux·rust·bevy·r36s·rk3326·开源掌机
阿童木写作9 小时前
Python实现Temu图片批量翻译自动化教程
运维·人工智能·python·自动化
kisloy9 小时前
【爬虫入门第13讲】Scrapy 框架深度解析(四)核心配置与自定义扩展
网络·爬虫·scrapy
ctlover10 小时前
Python学习第 5 日
学习