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

相关推荐
casual~1 分钟前
【学习记录】
学习·算法
Wils0nEdwards6 分钟前
技术栈的学习
学习
代码熬夜敲Q9 分钟前
网络工程相关
linux·服务器·网络
清辞85314 分钟前
入门大模型工程师第四课----通过RAG增强大模型原本无法回答的问题
大数据·人工智能·学习·语言模型
牢七14 分钟前
吾爱破解安卓逆向入门教程学习
学习
噜噜噜阿鲁~18 分钟前
python学习笔记 | 12.0、错误、调试和测试
笔记·python·学习
我先去打把游戏先22 分钟前
VMware NAT 模式 Ubuntu 虚拟机「宿主机能上网、虚拟机 ping 不通外网 + apt 更新卡死」全故障复盘
linux·运维·vscode·单片机·嵌入式硬件·ubuntu·keil5
开压路机25 分钟前
基础IO
linux·运维·服务器
三品吉他手会点灯28 分钟前
C语言学习笔记 - 46.运算符和表达式 - 运算符4 - 对初学运算符的一些建议
c语言·开发语言·笔记·学习
wangqiaowq36 分钟前
Rerank模型学习
学习