Products
GG网络技术分享 2026-01-24 21:57 3
说实话,每次打开Qt的源码我dou觉得自己像个傻子。真的,那种感觉就像是你在家里找袜子,后来啊翻出了一本外星语的字典。咱们今天就是要硬着头皮去kankan这个QTcpServer到底是个什么鬼东西。你说它是网络编程的核心吧,它确实挺核心的;你说它简单吧,kan那几层封装简直Neng把人绕晕。我就想问问写这些代码的大佬们,你们平时是不是dou不睡觉的?
咱们先不说别的,就说这个底层原理吧。其实我也不是特bie懂,dan是为了凑字数...哦不为了让大家明白,我必须得强撑着讲一讲。QTcpServer这个东西,说白了就是用来监听端口的。端口是什么?端口就是你家的大门编号嘛。有人敲门了你就要去开门。dan是这事儿变得特bie复杂。

不忍卒读。 源码里有个函数叫incomingConnection我kan这个名字kan了大概有一百遍才记住怎么拼。这个函数简直是整个服务器的灵魂啊!当你调用listen之后服务器就开始在那傻等了。等什么呢?等客户端连接啊!一旦有连接过来 Qt的事件循环就会像疯狗一样跳起来ran后调用这个incomingConnection。
我记得有一次调试这个函数,后来啊发现传进去的那个socketDescriptor居然是个负数!当时我就崩溃了负数是个什么鬼?难道是来自异世界的连接吗?后来查了半天资料才发现是自己逻辑写错了尴尬得我想找个地缝钻进去。这个socketDescriptor其实就是操作系统给你的一个句柄, 一个ID,你要拿着这个ID去创建真正的QTcpSocket,最后说一句。。
这里我得插一句题外话,现在的编译器真是太智Neng了也太笨了。智Neng的是它Neng帮你补全hen多代码,笨的是它经常在你不想补全的时候瞎补全。 性价比超高。 昨天我写代码的时候手一抖把整个项目dou给重构了吓得我冷汗dou出来了。
咱们来kankan下面这个表格吧, 虽然我也不知 弯道超车。 道为什么要放这里dan是感觉放这里显得比较专业:
| 排名 | 网络库名称 | 易用性评分 | 主要用途 |
|---|---|---|---|
| 1 | Qt Network | 9.5 | 跨平台应用开发 |
| 2 | Boost.Asio | 4.0 | 高性NengC++网络编程 |
| 3 | libevent | 6.5 | 事件驱动HTTP服务器 |
| 4 | ACE | 2.0 | 古老的分布式系统 |
| 5 | ZeroMQ | 7.5 | 消息队列中间件 |
你kan这表里Boost.Asio那个易用性评分才4.0我是真的给高了。用过的人dou知道那玩意儿模板元编程Neng把你逼疯。 到位。 比一比的话Qt真的是亲妈级别的待遇了。
接着刚才的话题说。在Linux底下一切皆文件。这 Socket 也是个文件描述符。但在Windows底下呢?它就是个句柄。Qt为了跨平台,把这些乱七八糟的东西dou封装起来了。你在kanQTcpServer源码的时候会发现一堆#ifdef QOSWIN32之类的宏定义。
也是醉了... kan着这些宏定义我就头疼。这就好比你在Zuo饭的时候,菜谱上写着“如guo你用的是煤气灶就炒三分钟,如guo是电磁炉就转五分钟”。烦不烦啊!dan是没办法,这就是跨平台的代价。源码解构的过程中你会发现,QTcpServerPrivate这个类干了hen多脏活累活。
比如说那个listen函数,你以为它是摆设吗?它里面调用了底层的::listen系统调用。如guo失败了怎么办?它会返回错误码。dan是hen多时候错误码特bie模糊,比如“Address already in use”。 反思一下。 哎呀我去,又是被占用!我明明把之前的进程dou杀掉了啊!后来才知道有个TIME_WAIT状态在那里作祟。这种细节如guo你不懂底层原理,真的Neng把键盘敲烂dou不知道问题在哪。
| I/O模型 | 并发性Neng | 开发难度 | 适用场景 |
|---|---|---|---|
| BIO | 极低 | 简单 | 学习Demo / 低并发工具 |
| NIO | 中等 | 困难 | 即时通讯游戏后台等 |
| AIO | 地狱级 | 超大规模服务器集群 | |
| 多路复用 | 高 | 中等偏难 | 主流Web服务器 / Qt Network |
QTcpServer 是tong过QAbstractSocketEngine 来跟底层打交道的 这个Engine类负责读写Socket描述符 你可yi把它想象成一个翻译官 把操作系统的翻译成QtNeng听懂的普通话
dan是我有时候觉得这个翻译官有点笨拙 比如说处理大包分包的时候 如guo你自己写协议解析稍微不注意 就会出现粘包现象 昨天我kan群里还有人问这个问题 我说你去搜搜去吧 这种问题问八百遍了 dou懒得打字解释
说到这里心情有点郁闷 为什么大家dou不爱kan文档呢 文档明明写得那么清楚 虽然是英文的 dan是现在的翻译插件那么多啊 唉 还是贴个表格缓解一下尴尬的情绪吧 这次来个IDE推荐表 毕竟kan源码还得靠好工具:
| IDE名称 | 代码高亮效果 | 索引速度 | 是否免费 |
|---|---|---|---|
| Visual Studio Code | 五彩斑斓的黑 | 快如闪电 | 是 |
| Qt Creator | 原生支持Zui好 | 一般 | 是 |
| CLion | fei常舒服 JetBrains出品必属精品) | 慢 | 否 |
| Vim/Neovim | 只有黑白全靠脑补颜色) | 瞬间完成 | 是 |
共勉。 hen多新手拿到QTcpServer 第一反应就是把它移到子线程里去 其实这未必是正确的Zuo法 主要原因是QTcpServer本身的设计并不是线程平安的 它只Neng在创建它的线程也就是主线程里调用listen等方法 dan是incomingConnection可yi在不同线程被触发吗 这就要kan你怎么重写了
如guo你想在子线程处理连接 你通常的Zuo法是在incomingConnection里拿到descriptorran后tong过信号槽发到工作线程去创建socket 这里就涉及到了对象依附性的问题 千万别搞错了 否则程序崩起来连渣dou不剩,说句可能得罪人的话...
Demand feedback