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

相关推荐
BIBI20492 小时前
VirtualBox 7.x 安装 Ubuntu 24 及增强功能配置、克隆虚拟机教程
linux·windows·ubuntu·环境搭建·安装教程·最佳实践·virtualbox
[shenhonglei]2 小时前
PolarDB-X Docker 部署与登录实战:从拉取镜像到客户端连接
运维·docker·容器
421!2 小时前
C语言学习笔记——10(结构体)
c语言·开发语言·笔记·stm32·学习·算法
weixin_462901972 小时前
HICKPI主板h618 Ubuntu / Armbian 镜像 SD安装
linux·运维·ubuntu
Lufeidata2 小时前
go语言学习记录-入门阶段2
学习·microsoft·golang
计算机学姐2 小时前
基于SpringBoot的在线课程学习网站
java·vue.js·spring boot·后端·学习·spring·intellij-idea
A.A呐2 小时前
【Linux第二十四章】IP协议
linux·网络
志栋智能2 小时前
超自动化巡检:构筑业务连续性的第一道智能防线
大数据·运维·网络·人工智能·自动化
llkk星期五2 小时前
ubuntu(24.04)下wayland显示界面带来的影响
linux·ubuntu