极客时间已完结课程限时免费阅读

09丨答疑篇:学习网络编程前,需要准备哪些东西?

09丨答疑篇:学习网络编程前,需要准备哪些东西?-极客时间

09丨答疑篇:学习网络编程前,需要准备哪些东西?

讲述:冯永吉

时长10:44大小9.82M

你好,我是盛延敏,这里是网络编程实战第 9 讲,欢迎回来。
今天是基础篇的最后一讲。在这一讲中,我将会针对基础篇中大家提出的普遍问题进行总结和答疑,让我们整理一下,再接着学习下一个模块的内容。

代码和环境

既然我希望通过学习,可以带你进行网络编程实战,那么就得有一个环境,可以运行文章中的例子,并加以活学活用。
我已经将代码上传到 GitHub 中,你可以访问以下地址来获得最新的代码。
代码按照章节组织,比如 chap-7 就对应第七篇文章。
代码按照 CMake 组织,CMake 是一个跨平台的编译管理系统,使用 CMake 可以方便地在 Linux 等类 UNIX 系统下动态生成 Makefile,再由 make 工具编译、链接生成二进制文件。当然,CMake 也可以支持 Windows 系统下的 C/C++ 编译,这里我们就不展开了。
所有的代码我都已经测试过,可以运行在 Linux 和 MacOS 上。

Ubuntu 系统

在 Linux 下,如果你是 Ubuntu 系统,需要安装 Cmake、make 和 gcc/g++ 等编译系统和工具。
sudo apt-get install gcc g++ make cmake
如果是 CentOS 或 Red Hat,需要执行 yum install 命令:
sudo yum install gcc g++ make cmake
使用 CMake 编译程序需要两步,第一步执行 Cmake 生成配置文件,主要是 Makefile;具体做法是执行如下的 cmake 命令,之后在 build 目录下,会发现 CMake 根据系统环境如编译器、头文件等自动生成了一份 Makefile:
cd build && cmake -f ../
接下来执行第二步,在 build 目录运行 make,让 make 驱动 gcc 编译、链接生成二进制可执行程序,这个过程可能会持续几分钟。最后在 build/bin 目录下,会生成所有可运行的二进制程序。
-rwxr-xr-x 1 vagrant vagrant 13944 Aug 18 13:45 addressused*
-rwxr-xr-x 1 vagrant vagrant 14000 Aug 18 13:45 addressused02*
-rwxr-xr-x 1 vagrant vagrant 13848 Aug 18 13:45 batchwrite*
-rwxr-xr-x 1 vagrant vagrant 13800 Aug 18 13:45 bufferclient*
-rwxr-xr-x 1 vagrant vagrant 14192 Aug 18 13:45 graceclient*
-rwxr-xr-x 1 vagrant vagrant 14096 Aug 18 13:45 graceserver*
-rwxr-xr-x 1 vagrant vagrant 8960 Aug 18 13:45 make_socket*
-rwxr-xr-x 1 vagrant vagrant 13920 Aug 18 13:45 pingclient*
-rwxr-xr-x 1 vagrant vagrant 14176 Aug 18 13:45 pingserver*
-rwxr-xr-x 1 vagrant vagrant 13976 Aug 18 13:45 reliable_client01*
-rwxr-xr-x 1 vagrant vagrant 13832 Aug 18 13:45 reliable_client02*
-rwxr-xr-x 1 vagrant vagrant 14120 Aug 18 13:45 reliable_server01*
-rwxr-xr-x 1 vagrant vagrant 14040 Aug 18 13:45 reliable_server02*
-rwxr-xr-x 1 vagrant vagrant 14136 Aug 18 13:45 samplebuffer01*
-rwxr-xr-x 1 vagrant vagrant 13864 Aug 18 13:45 samplebuffer02*
-rwxr-xr-x 1 vagrant vagrant 14392 Aug 18 13:45 samplebuffer03*
-rwxr-xr-x 1 vagrant vagrant 13848 Aug 18 13:45 streamclient*
-rwxr-xr-x 1 vagrant vagrant 14392 Aug 18 13:45 streamserver*
-rwxr-xr-x 1 vagrant vagrant 13784 Aug 18 13:45 tcpclient*
-rwxr-xr-x 1 vagrant vagrant 13856 Aug 18 13:45 tcpserver*
-rwxr-xr-x 1 vagrant vagrant 13936 Aug 18 13:45 udpclient*
-rwxr-xr-x 1 vagrant vagrant 13320 Aug 18 13:45 udpserver*
-rwxr-xr-x 1 vagrant vagrant 13936 Aug 18 13:45 unixdataclient*
-rwxr-xr-x 1 vagrant vagrant 13896 Aug 18 13:45 unixdataserver*
-rwxr-xr-x 1 vagrant vagrant 13800 Aug 18 13:45 unixstreamclient*
-rwxr-xr-x 1 vagrant vagrant 13992 Aug 18 13:45 unixstreamserver*

MacOS

在 MacOS 上,Cmake 和 make 都会有 Mac 特定版本,并且实现的原理也是基本一致的,我们可以像上面 Ubuntu 系统一样手动安装、配置这些工具。
如果你的系统上没有这两个软件,可以使用 brew 安装 Cmake 和 make。
brew install cmake
brew install make
MacOS 上 C/C++ 语言的编译器不同于 GNU-GCC,是一个叫做 Clang 的东西。Clang 背后的技术叫做 LLVM(Low Level Virtual Machine)。LLVM 是以 BSD License 开发的开源编译器框架系统,基于 C++ 编写而成,不仅可以支持 C/C++,还可以支持 Swift、Rust 等语言。
如果你在 MaxOS 上查看 Clang 的版本信息,可以很明显地看到,Clang 是基于 LLVM 开发的,并且对应的版本是多少。在我的机器上显示的 LLVM 版本是 10.0.0。
clang -v
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
下面是在 MacOS 上执行 Cmake 和 make,使用 Clang 完成编译和链接的过程。
cd build && cmake -f ../
-- The C compiler identification is AppleClang 10.0.0.10001044
-- The CXX compiler identification is AppleClang 10.0.0.10001044
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/shengym/Code/network/yolanda/test
cd build && make
可执行程序仍然保存在 build/bin 目录下面。

CLion

对于有 IDE 情结的同学来说,推荐使用 JetBrains 公司出品的 CLion 进行编译和调试。
你可以在这里下载 https://www.jetbrains.com/clion/, 获得 30 天的免费使用。
CLion 自带了 CMake 等工具,可以开箱即用。它最强大的地方,是可以直接设置断点,方便进行调试。我们进入主菜单,选择 Run,再选择 Debug,就可以启动程序,进行调试。
有些情况下,启动程序时需要输入一些参数,这个时候需要使用“Edit Configurations”为可执行程序配置参数。下面是一个例子:

Windows

使用 Windows 系统 + CLion 的同学,可以在 Win10 应用商店中下载一个 Ubuntu 版本的 Windows 子系统,即 WSL,然后在 CLion 中配置工程的环境为 WSL 即可编译运行。

学习路径

也许你刚刚入门,一直对网络编程的学习路径有很大的困惑,我在这里统一回复一下。
我觉得学习网络编程技术,必须要过一道语言关,这个语言就是 C 语言。专栏本身也是基于 C 语言的。虽然现代工业化语言如 Java、Golang 等已经足够强大,但是你要知道,在这些语言的背后,无一例外的总是有 C 语言的影子。C 语言是可以和系统直接交互的语言,无论是系统调用,还是内核实现,都和 C 语言有非常直接的联系,比如 Java 本身就是用 C++ 实现的,Golang 虽然现在可以自举,也就是可以使用 Golang 实现 Golang 本身,但是它的第一版也是用 C/C++ 实现的。
我不建议一开始就学习 C++ 语言,在我看来, C++ 语言在 C 语言原来的基础上做了很多语言层面的增强,而这些增强的语言特性,例如模板、继承、虚函数、boost 语言库等,对于刚开始接触底层的人显得有些艰深。
学习一门编程语言,显然不是学习这门语言的控制流或者变量类型,而是抓住这门语言的精髓。我认为 C 语言的精髓包括数组和指针、结构体和函数。
C 语言的地址、数组、指针可以帮助我们详细地理解计算机的体系结构,一段数据怎样在内存中摆放,怎么去访问等,你可以在学习它们的过程中得到锤炼,了解这些基础的编程理念。
有些同学一上来就啃“TCP/IP 协议”,我觉得对于实战来说,显得过于着急。我们可以把“TCP/IP 协议”当作编程过程中答疑解惑的好帮手,有问题之后再从中寻找答案,而不是急急忙忙就来啃这类书籍。说实话,这类书籍理论性偏强,有时候大段读下来也少有收获。
最好的办法,还是自己跟随一些入门书籍,或者我的这篇实战,尝试动手去写、去调试代码,这中间你会不断获得一些反馈,然后再和大家一起探讨,不断加深了解。
当你学到了一定阶段,就可以给自己开一些小的任务,比如写一个聊天室程序,或者写一个 HTTP 服务器端程序,带着任务去学习,获得成就感的同时,对网络编程的理解也随之更上一层楼了。

书籍推荐

我希望你可以通过这个专栏更好地了解网络编程,但是深入的学习还需要你自行去找更多的资料。我在这里给你推荐一些书,这些书是各个领域的经典。
C 语言入门方面,我推荐 《C 程序设计语言》,这里是豆瓣链接,你可以看下大家的评价以及他们的学习方式: https://book.douban.com/subject/1139336/
UNIX 网络编程方面,强烈推荐 Stevens 大神的两卷本《UNIX 网络编程》,其中第一卷是讲套接字的,第二卷是讲 IPC 进程间通信的。这套书也随书配备了源代码,你如果有兴趣的话,可以对代码进行改写和调试。
这套书的卷一基本上面面俱到地讲述了 UNIX 网络编程的方方面面,但有时候稍显啰嗦,特别是高性能高并发这块,已经跟不上时代,但你可以把注意力放在卷一的前半部分。
这套书翻译了好几版,就我的体验来说,比较推荐杨继张翻译的版本。
TCP/IP 协议方面,当然是推荐 Stevens 的大作《TCP/IP 详解》, 这套书总共有三卷,第一卷讲协议,第二卷讲实现,第三卷讲 TCP 事务。我在这里推荐第一卷,第二卷的实现是基于 BSD 的代码讲解的,就不推荐了。我想如果你想看源码的话,还是推荐看 Linux 的,毕竟我们用的比较多。第三卷涉及的内容比较少见,也不推荐了。
这套书各个出版社翻译了好多版本,你可以去豆瓣自行查看哪个版本评分比较高。
《TCP/IP 详解 卷 1:协议》豆瓣链接如下:
最后除了书籍外,还有一个非常好的了解 TCP 的方法,那就是查看 RFC 文档,对于有一定英文能力的同学来说,可以说是一个捷径。RFC 最大的好处可以帮我们了解 TCP 发展的背景和脉络。

疑难解答

前面的内容算是我对你学习网络编程提供的一些小建议或者小帮助。接下来,我们正式进入到文章本身的内容。
在第 5 讲思考题部分中,我出了这么一道题目“一段数据流从应用程序发送端,一直到应用程序接收端,总共经过了多少次拷贝?”大家的回答五花八门。
我的本意可以用一张图来表示,还记得 TCP/IP 层次模型么?我想通过这么一个问题,来展示 TCP/IP 分层的思想。
让我们先看发送端,当应用程序将数据发送到发送缓冲区时,调用的是 send 或 write 方法,如果缓存中没有空间,系统调用就会失败或者阻塞。我们说,这个动作事实上是一次“显式拷贝”。而在这之后,数据将会按照 TCP/IP 的分层再次进行拷贝,这层的拷贝对我们来说就不是显式的了。
接下来轮到 TCP 协议栈工作,创建 Packet 报文,并把报文发送到传输队列中(qdisc),传输队列是一个典型的 FIFO 队列,队列的最大值可以通过 ifconfig 命令输出的 txqueuelen 来查看。通常情况下,这个值有几千报文大小。
TX ring 在网络驱动和网卡之间,也是一个传输请求的队列。
网卡作为物理设备工作在物理层,主要工作是把要发送的报文保存到内部的缓存中,并发送出去。
接下来再看接收端,报文首先到达网卡,由网卡保存在自己的接收缓存中,接下来报文被发送至网络驱动和网卡之间的 RX ring,网络驱动从 RX ring 获取报文 ,然后把报文发送到上层。
这里值得注意的是,网络驱动和上层之间没有缓存,因为网络驱动使用 Napi 进行数据传输。因此,可以认为上层直接从 RX ring 中读取报文。
最后,报文的数据保存在套接字接收缓存中,应用程序从套接字接收缓存中读取数据。
这就是数据流从应用程序发送端,一直到应用程序接收端的整个过程,你看懂了吗?
上面的任何一个环节稍有积压,都会对程序性能产生影响。但好消息是,内核和网络设备供应商已经帮我们把一切都打点好了,我们看到和用到的,其实只是冰山上的一角而已。
这就是基础篇的总结与答疑部分,我先对之前基础篇的内容补充了一些资料,尽可能地为你学习网络编程提供方便,然后针对大家有明显疑惑的问题进行了解答,希望对你有所帮助。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 34

提建议

上一篇
08 | 工欲善其事必先利其器:学会使用各种工具
下一篇
10 | TIME_WAIT:隐藏在细节下的魔鬼
unpreview
 写留言

精选留言(40)

  • 传说中的成大大
    2019-08-21
    所以最终是拷贝了六次?
    15
  • HunterYuan
    2019-11-30
    最近在做网络吞吐的性能优化,涉及到网卡多队列,NAPI减少中断,软件多队列,CPU绑定不同的队列,以及socket与内核之间的交互进行共享内存的实现,应用层层采用多线程进行不同数据的处理之后。再回头看老师的讲解,对照内核协议栈源码,感觉收获颇多,感谢感谢。

    作者回复: 你做的东西挺艰深的哈,有时间可以给大家分享分享。

    10
  • ly
    2019-08-21
    哈哈,和老师灵魂碰撞了,unix的网络编程卷1和2昨天下单的。 按照第5章的相关逻辑自己用Java写了一段demo程序。 【Java代码逻辑】 服务端接收 1024 字节(read)就休眠1秒钟; 客户端for循环50次,每1次for循环写 10 * 1024 字节出去(write/flush)。 【现象】 服务端间隔1秒打印出接收到的1024字节数据。 客户端发送完几乎每发送1024*10字节以后会阻塞一会,然后接着再发送1024*10字节,但是客户端发送完所有数据退出时,服务端还在不断的接收打印。 【wireshark抓包片段】 (56725客户端端口,8888服务端端口) ------------------------------------------------------------ ...... 56725 > 8888 [ACK] Seq=1 Ack=1 Win=8192 Len=1460 56725 > 8888 [ACK] Seq=1461 Ack=1 Win=8192 Len=1460 8888 > 56725 [ACK] Seq=1 Ack=2921 Win=8192 Len=0 56725 > 8888 [ACK] Seq=2921 Ack=1 Win=8192 Len=1460 56725 > 8888 [ACK] Seq=4381 Ack=1 Win=8192 Len=1460 56725 > 8888 [ACK] Seq=5841 Ack=1 Win=8192 Len=1460 56725 > 8888 [ACK] Seq=7301 Ack=1 Win=8192 Len=1460 8888 > 56725 [ACK] Seq=1 Ack=8761 Win=8192 Len=0 ...... ------------------------------------------------------------ 观察的期间会出现一些 TCP Window Full / TCP window Update 等标记。 【个人理解】 客户端之所以发送 1024*10 字节以后会阻塞,应该是发送端的速度大于了接收端的速度,TCP协议会自动对发送方限流,又或者是因为本地发送缓冲区满了,需要阻塞发送方。 【疑问】 1. 为什么客户端向服务端发送数据的时候,wireShark显示的是 [ACK] 应答标记,我记得之前发送比较少的数据时显示的是 [PSH+ACK]标记? 2. TCP Window Full/TCP window Update 这些标记什么时候会出现,代表什么意思呢? 请老师点评。。。。
    展开

    作者回复: 第一个是为了更好的利用带宽,在发送数据的同时捎带传输ACK报文,这个是和具体场景有关的,并不一定每次都会起作用。 第二个应该是发送窗口和接收窗口的同步报文。

    共 2 条评论
    9
  • 2019-11-23
    哈哈,看完之后还是不确定拷贝了几次,老师为啥不先给明确的结论,再解释你给结论的依据呢?😄

    作者回复: 这个本身就没有确切的答案,主要是对网络协议栈加强整体的认识就可以了。

    6
  • supermouse
    2019-11-03
    使用 Windows 系统 + CLion 的同学,可以在 Win10 应用商店中下载一个 Ubuntu 版本的 Windows 子系统,即 WSL,然后在 CLion 中配置工程的环境为 WSL 即可编译运行。亲测可用。

    作者回复: 赞,我让编辑把这段加进去。感谢。

    共 3 条评论
    5
  • Geek_404738
    2019-09-25
    对于那个网卡分层逻辑图,非常好。在实际工作中,怎样分析出是哪个环节的缓冲出问题呢。我是做测试,很想了解这个。

    作者回复: 抓包, troubleshooting,需要时间慢慢磨练

    3
  • 0ver10@d
    2019-08-22
    根据最后一张图,对于接收方,是必须要等到数据存入到最上面的接收缓冲区后,操作系统才会发送ACK?还是当数据从Rx ring取出后ACK就可以发送了?或者是必须要等应用程序将数据从接收缓冲区读出后才发出?

    作者回复: 应该是最上面的TCP层,因为这是TCP层在控制ACK等报文。

    3
  • Gougle
    2020-03-03
    [ 96%] Linking C executable ../bin/aio01 ld: library not found for -lrt clang: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [bin/aio01] Error 1 make[1]: *** [chap-30/CMakeFiles/aio01.dir/all] Error 2 make: *** [all] Error 2 老师MacOS编不过
    展开

    作者回复: 这个好多同学反映了,我发现都是rt这个库的问题,删掉这个库就好了,新版的Mac和Linux都不需要再显示指定这个库。 同步下代码再编译下。

    共 3 条评论
    2
  • Tunayoyo
    2019-09-13
    老师,中秋快乐。 请您讲讲Windows上CLion怎么运行你写的代码吧,基本流程提下,谢谢了!

    作者回复: 哦,这个,基本上有点难哎,头文件可能都不一样,你可以在windows上装虚拟机来跑,或者用cygwin,这样的话跑CLion可能有问题。。。。

    共 3 条评论
    2
  • Mosea
    2022-01-17
    [ 97%] Linking C executable ../bin/aio01 /usr/bin/ld: CMakeFiles/aio01.dir/aio01.c.o: in function `main': aio01.c:(.text+0x1e9): undefined reference to `aio_write' /usr/bin/ld: aio01.c:(.text+0x242): undefined reference to `aio_error' /usr/bin/ld: aio01.c:(.text+0x256): undefined reference to `aio_error' /usr/bin/ld: aio01.c:(.text+0x26b): undefined reference to `aio_return' /usr/bin/ld: aio01.c:(.text+0x3c8): undefined reference to `aio_read' /usr/bin/ld: aio01.c:(.text+0x418): undefined reference to `aio_error' /usr/bin/ld: aio01.c:(.text+0x42c): undefined reference to `aio_return' collect2: error: ld returned 1 exit status make[2]: *** [chap-30/CMakeFiles/aio01.dir/build.make:85: bin/aio01] Error 1 make[1]: *** [CMakeFiles/Makefile2:1917: chap-30/CMakeFiles/aio01.dir/all] Error 2 make: *** [Makefile:130: all] Error 2 老师,我的环境是Ubuntu20 cmake之后,Makefile文件已经生成,执行make的文件的时候,出现这个错误,看错误好像是链接的时候找不到相关文件,老师的GitHub仓库也有人问相关的问题。https://github.com/froghui/yolanda/issues/25 现在还没有人回答,可以问一下老师这个问题如何解决吗?
    展开

    作者回复: /chap-30/CMakeList.txt 的最后一行改为 target_link_libraries(aio01 yolanda rt), 加上rt这个动态库试试?

    1
  • Geek_82b16d
    2021-04-19
    我需要添加 target_link_libraries(aio01 rt) 才能编译成功 aio部分 ubuntu

    作者回复: 嗯,确实有些环境要把aio的库加进来。这个问题,已经来来回回好几次了。搞好就可以。

    1
  • jiapeish
    2020-03-04
    MacOS里运行程序, /User/CLionProjects/yolanda/cmake-build-debug/bin/pingclient 127.0.0.1 connect failed : Connection refused (61) Process finished with exit code 1

    作者回复: 服务端程序没有起来,你看看对应的端口有没有服务。

    1
  • 酸葡萄
    2019-09-28
    老师请教一个问题,一直做的的是windows下的开发,用的vs,linux环境下的开发也就用clion写写demo,像那种linux服务开发岗日常工作中难道都用vim开发的吗?vim写个小程序,gdb调试我倒还能理解,像那种动辄数万行,数十万代码,几百个或以上的项目难道也都不用IDE的吗?

    作者回复: 这个看个人习惯了,我见过用vim开发的,也见过用vs、clion IDE开发的,个人觉得只要释放生产力就行。 我个人是用IDE的,vim只写一些脚本。

    1
  • Vfeelit
    2019-09-28
    一直有几个困惑,希望老师可以解惑。 TCP协议,在发送数据时会先拷贝数据到发送缓冲区,如果数据比较大,马上塞满了发送缓冲区,这个时候必须把数据发出去应用程序才能继续拷贝数据进来,困惑地方是,到达IP层后,TCP报文是否会被拆分成多个IP包? 如果不会,那么TCP报文最大只能是发送缓冲区大小? 另外,在UDP中,如果要发送的数据超过发送缓冲区,数据会被截断?
    展开

    作者回复: TCP报文会被拆分成IP报文的,这个是由协议栈帮助完成的。 有两个因素值得考虑, 第一个是缓冲区大小不是你想象那么小的,一般情况下都能容纳下应用层的信息; 第二个是应用程序往缓冲区拷贝数据,不是100%会成功,特别是在非阻塞的情况下,拷贝完之后应用程序需要配合缓冲区情况继续完成没有拷贝成功的部分,不存在数据被截断的情况。

    1
  • 姑射仙人
    2019-09-16
    windows上可以用Cygwin来搭建开发环境,安装cmake,make,gcc,g++等包,虽然不可能完全模拟linux上的环境,但是大部分代码修修补补也是可以运行起来的。

    作者回复: 是的,但终归还是一个"伪"模拟环境。

    1
  • 码农Kevin亮
    2019-09-09
    平常都用JAVA,没用过Clion也没接触过CMake,下载了Clion后搞来搞去都报错,说文件路径有问题。求助

    作者回复: 把你的错误贴上来,大家一起帮你看看

    1
  • 石将从
    2019-08-21
    老师,你这个环境省略了好多东西啊,cd build && cmake -f ../ 哪里的Build目录呀

    作者回复: 当前路径mkdir build就可以了

    共 2 条评论
    1
  • 传说中的成大大
    2019-08-21
    那个build目录是那个路径下的啊?我感觉都是系统路径下呢

    作者回复: 当前路径mkdir build

    共 2 条评论
    1
  • 马仔
    2019-08-21
    我想学习Linux代码在window上的porting,但是网上的资料都比较散。老师可以推荐一些比较完整的资料吗。

    作者回复: 这个我不是专家,不过我觉得你可以试着一个一个尝试,碰到问题翻翻msdn

    1
  • 三年二班邱小东
    2022-02-23
    make[2]: Warning: File 'CMakeFiles/make_socket.dir/depend.make' has modification time 1.8 s in the future [ 50%] Building C object CMakeFiles/make_socket.dir/make_socket.c.o [100%] Linking C executable make_socket /usr/bin/ld: cannot find -lyolanda collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/make_socket.dir/build.make:84: make_socket] Error 1 make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/make_socket.dir/all] Error 2 make: *** [Makefile:84: all] Error 2 老师我的环境是WSL+gcc,第一次接触链接库,链接库的时候没有找到yolanda,应该如何解决呢?
    展开

    作者回复: 感觉你没有编译我的lib库啊。你是按照文章指南编译的么?