罗剑锋的C++实战笔记
罗剑锋
奇虎360技术专家,Nginx/OpenResty开源项目贡献者
立即订阅
3613 人已学习
课程目录
已更新 25 讲 / 共 30 讲
0/4登录后,你可以任选4讲全文学习。
课前导读 (2讲)
开篇词 | 把C++从“神坛”上拉下来,这次咱这么学
免费
课前准备 | 搭建实验环境
概论 (5讲)
01 | 重新认识C++:生命周期和编程范式
02 | 编码阶段能做什么:秀出好的code style
03 | 预处理阶段能做什么:宏定义和条件编译
04 | 编译阶段能做什么:属性和静态断言
05 | 面向对象编程:怎样才能写出一个“好”的类?
语言特性 (5讲)
06 | auto/decltype:为什么要有自动类型推导?
07 | const/volatile/mutable:常量/变量究竟是怎么回事?
08 | smart_ptr:智能指针到底“智能”在哪里?
09 | exception:怎样才能用好异常?
10 | lambda:函数式编程带来了什么?
标准库 (4讲)
11 | 一枝独秀的字符串:C++也能处理文本?
12 | 三分天下的容器:恰当选择,事半功倍
13 | 五花八门的算法:不要再手写for循环了
14 | 十面埋伏的并发:多线程真的很难吗?
技能进阶 (4讲)
15 | 序列化:简单通用的数据交换格式有哪些?
16 | 网络通信:我不想写原生Socket
17 | 脚本语言:搭建高性能的混合系统
18 | 性能分析:找出程序的瓶颈
总结篇 (2讲)
19 | 设计模式(上):C++与设计模式有啥关系?
20 | 设计模式(下):C++是怎么应用设计模式的?
轻松话题 (3讲)
轻松话题(一) | 4本值得一读再读的经典好书
轻松话题(二) | 给你分享我的工作百宝箱
轻松话题(三) | 提高生活质量的App
罗剑锋的C++实战笔记
15
15
1.0x
00:00/00:00
登录|注册

16 | 网络通信:我不想写原生Socket

罗剑锋 2020-06-11
你好,我是 Chrono。
在上一节课,我讲了 JSON、MessagePack 和 ProtoBuffer 这三种数据交换格式。现在,我们手里有了这些跨语言、跨平台的通用数据,该怎么与外部通信交换呢?
你肯定首先想到的就是 Socket 网络编程,使用 TCP/IP 协议栈收发数据,这样不仅可以在本地的进程间通信,也可以在主机、机房之间异地通信。
大方向上这是没错的,但你也肯定知道,原生的 Socket API 非常底层,要考虑很多细节,比如 TIME_WAIT、CLOSE_WAIT、REUSEADDR 等,如果再加上异步就更复杂了。
虽然你可能看过、学过不少这方面的资料,对如何处理这些问题“胸有成竹”,但无论如何,像 Socket 建连 / 断连、协议格式解析、网络参数调整等,都要自己动手做,想要“凭空”写出一个健壮可靠的网络应用程序还是相当麻烦的。
所以,今天我就来谈谈 C++ 里的几个好用的网络通信库:libcurl、cpr 和 ZMQ,让你摆脱使用原生 Socket 编程的烦恼。

libcurl:高可移植、功能丰富的通信库

第一个要说的库是 libcurl,它来源于著名的curl 项目,也是 curl 的底层核心。
libcurl 经过了多年的开发和实际项目的验证,非常稳定可靠,拥有上百万的用户,其中不乏 Apple、Facebook、Google、Netflix 等大公司。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《罗剑锋的C++实战笔记》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(17)

  • 赖阿甘
    说实在在看文章之前,我还不知道ZMQ这个网络通信库,哈哈。老师怎么没提到libevent、libev、asio、muduo等网络通信库,是否这些库的接口比较原始,不好用,还望解答

    作者回复: 你说的很对,这些库用起来比较复杂,一时半会说不清楚,光里面的epoll、多线程机制就要解释半天,要用起来更是要很多步骤。

    我的想法还是让大家尽量快速上手,能用起来最重要。

    2020-06-11
    6
  • robonix
    疑惑同楼上~ ASIO 据说要加到c++ 20了,应该介绍呀?

    作者回复: asio推迟到了C++23,而且从它的前身boost.asio来看,用起来也是很复杂的,里面的概念很多,不好一下子说清楚,以后如果有机会可以专门写一篇。

    2020-06-11
    2
  • 编程国学
    军工行业,用户强调实时,一般采用udp,目前我们采用qt 自己的库,有没有好的建议

    作者回复: qt我没用过,不好评价,我觉得可以试试zmq,它的性能也很不错。

    2020-06-11
    2
  • 屈肖东
    老师什么时候可以推荐几个值得读的比较通用的开源代码,因为很多开源代码虽然很好,但是太过复杂庞大,很难阅读。或者写一篇针对如何更好的阅读源码的文章。毕竟读代码应该是学习写代码最好的方式

    作者回复: C++开源库很多都比较大、比较复杂,找合适学习的还真不是件容易的事情。

    我觉得比较好的开始方式是看课程里推荐的这几个库,都不是特别大,功能比较单一,比较容易聚焦学习点。

    看的时候可以先从代码风格看起,再熟悉C++关键字的用法,再到整体架构、接口设计。不能心急,不要想着几天或者一个月就能看完。而且也没必要完全看懂,只要能从中学到一两个点就可以说是值得了。

    2020-06-15
    1
  • 黄骏
    之前用过zmq,他的创始人也非常传奇

    作者回复: zmq算是老牌的消息中间件了,用的比较广泛,不过确实有点老。

    2020-06-11
    1
  • lckfa李钊
    涨知识了,之前http通信一直使用的原生 libcurl,看起来现在可以转cpr了,不是不知道这个库的存在,只是没人推荐不敢换而已。另外ZMQ,这个库看起来可以解决手写TCP/IP通信的问题,后面会试试。
    网络编程最大的坑其实是不懂网络协议,以及联调的问题,感觉不是库能解决的。但是库能解决底层封装,避免重复造轮子的痛苦。

    作者回复: 对,这些通讯库可以减轻底层的一部分工作,把时间和精力集中在上层应用上。

    2020-06-11
    1
  • wonderNick
    老师推荐的 json for modern C++ cpr ZMQ 真的都是实用的好东西啊,看的时候就很激动。下一阶段落地到我们的项目中,预计可以使我们的工程的可读性和易用性,有较大的提升。
    思考题:
    1.之前我们在 局域网通信时,客户端发送至服务端的数据出现了粘包,导致数据解析出错,这个问题我们通过限定数据流长度的方式得以解决。
    2.还没有实际应用,先上手练练,后续会回来补充答案

    作者回复: 粘包在自己处理底层通信的时候是个很烦人的问题,zmq可以很好地解决,保证拿到的是一个完整可靠的消息。

    不过要用好这些库还是要仔细阅读它们的文档,因为C++的东西都有可能有隐藏的坑,所以不了解的特性就要尽量少用。

    2020-06-18
  • 范闲
    zmq是可以做成服务端的是吧?那这个除了易用性,和其他网络库相比还有啥优势呢?另外cpp的rpc框架其实也都提供了这些功能,是否用rpc更合理?

    作者回复:
    1.zmq是消息中间件,可以保证消息不丢失,准确送达。

    2.rpc适用于开发请求-响应的场景,是远程调用,而zmq是更底层一些的网络传输库,所以应用范围就更广。

    2020-06-15
  • 朱熙
    老师您好,有一个caf的框架,希望可以在之后的课程里有机会能分析下优劣,是一个多线程的框架,包括线程间的通信

    作者回复: 大概看了一下,挺有意思的,可惜要求gcc>7,这在很多老系统上满足不了要求。

    2020-06-13
  • 王珏大大
    请问老师,“ZMQ 环境的线程数” 这是什么设置吗,如何设置?

    作者回复: 这个是zmq内部的工作线程数量,开多个线程可以增加zmq的处理能力。

    2020-06-12
  • java2c++
    cpr::Url{"http://openresty.org"} // 传递URL
    );
    URL 使用 Url 类,它其实是 string 的别名;

    这个地方的语法没有看懂,Url后面跟个大括号{}表示什么意思,是Url的匿名子类吗

    作者回复: 花括号是C++11的新初始化语法,和圆括号的构造函数类似,用这种形式看起来更清楚一些,也和Python比较像。

    2020-06-12
  • 幻境之桥
    这几个库都很 nice 👍🏻
    cpp 有类似 JAVA Netty 这样的框架吗?
    或者上面这些有可以方便实现自定义协议的吗?

    作者回复: 很遗憾,目前C++还没有非常完善易用的高级框架,rpc框架倒是有一些。

    2020-06-12
  • 土土人
    ASIO使用起来极其别扭

    作者回复: 可能是因为它用的是proactor吧,但设计架构还是挺好的,作为底层比较合适,如果在上面有高级封装库就好了。

    2020-06-12
  • 木瓜777
    zmp是否支持websocket?

    作者回复: 不支持,它用的是自己的协议,不走标准。

    2020-06-12
  • TC128
    HP-Socket有人用吗?

    作者回复: 我没用过,简单搜了一下,感觉还不错,可以一试。

    2020-06-11
  • Confidant.
    老师,zmq的代码有一个lamda用&捕获的错误,你的都可以编过吗?

    作者回复: GitHub上的代码都用g++5.4编译通过的,注意用std=C++14,可以看一下源码开头的注释。

    如果还不行,可以在GitHub上提issue。

    2020-06-11
    2
  • Jason
    前段时间遇到过一个问题,通过http发送图片数据老是发送不全,最终定位到有两个原因:一是因为Linux 系统的TCP 缓冲区太小,通过/etc/sysctl.conf设置解决;二是因为代码中socket的SO_SNDBUF参数不够大,通过setsockopt函数重新设置解决。如果用老师说的这三个库来开发的话,不知道会不会遇到上面的问题?

    作者回复:
    1.系统的问题,libcurl肯定解决不了,得外部调整。

    2.可以用函数Curl_sndbufset()调整,源码在lib/connect.c。不过我看它只在Windows上生效,Linux下是空的,所以在linux上应该不需要用这个。可以用libcurl试验一下,我还没有遇到过你这样的问题。

    3.zmq不用担心这个问题,它属于mq,会自动处理大数据。

    2020-06-11
收起评论
17
返回
顶部