当前位置: 首页 > news >正文

使用Github项目nghttp3的样例学习HTTP/3

文章目录

  • 前言
  • 一、HTTP3测试 in Ubuntu
    • 1.1. 基本软件
    • 1.2. gcc/g++
      • 1.2.1. Ubuntu22
      • 1.2.2. Ubuntu20
        • 1.2.2.1. 必备库
          • 1.2.2.1.1. gmp
          • 1.2.2.1.2. mpfr
          • 1.2.2.1.3. mpc
        • 1.2.2.2. 安装
    • 1.3. libev >= 4.11(备用)
      • 1.3.1. 安装
      • 1.3.2. 测试
    • 1.4. nghttp3
    • 1.5. ngtcp2 build with wolfSSL
      • 1.5.1. wolfSSL >= 5.7.0
      • 1.5.2. ngtcp2
      • 1.5.3. 使用
        • 1.5.3.1. server
      • 1.5.3.2. client
    • 1.6. ngtcp2 build with LibreSSL(可选)
      • 1.6.1. LibreSSL
      • 1.6.2. ngtcp2
    • 1.7. Wireshark
  • 二、HTTP3测试 in CentOS8.5


前言

nghttp3是Github上的一个基于C语言的HTTP/3库,它使用的QUIC协议则由ngtcp2库实现,并且可以从该库中编译出若干二进制文件形式的样例以供入门,本文参考项目说明,分享个人从软件安装到样例使用的全过程。

如果后续计划使用的Linux系统为Ubuntu,建议至少为Ubuntu 22。


一、HTTP3测试 in Ubuntu

1.1. 基本软件

名称操作
pkg-config >= 0.20sudo apt install pkg-config -y && pkg-config --version
autoconfsudo apt install autoconf -y
automakeautomake --version
autotools-devapt search autotools-dev
libev-devsudo apt install libev-dev
libtoolsudo apt install libtool -y
makesudo apt install make

1.2. gcc/g++

后续编译ngtcp2的项目时,正常情况下会编译出若干个可执行文件,但这要求g++能够支持C++20的特性,否则在编译时会提示如下信息:

在这里插入图片描述
因此,gcc/g++的版本至少为v11。

1.2.1. Ubuntu22

Ubuntu22.4默认使用的gcc和g++版本为v11,可以通过apt安装的最高版本为v12,但是需要额外操作以指定版本。

首先通过apt安装gcc-12和g+±12:

sudo apt install gcc-12 g++-12 -y

此时可以通过gcc-12命令来使用v12版本的gcc,但是使用gcc命令时仍会提示找不到该命令或者使用的旧版本。

在这里插入图片描述

将gcc-12添加到update-alternatives工具中,设置其为gcc的软链接,同时设置从属的g++:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 20 --slave /usr/bin/g++ g++ /usr/bin/g++-12

确认版本配置:

sudo update-alternatives --config gcc

此时即可通过gcc命令来使用gcc-12。

在这里插入图片描述

1.2.2. Ubuntu20

Ubuntu20.4通过apt可安装的gcc版本最高为v10,因此只能使用源码安装gcc12。

1.2.2.1. 必备库
1.2.2.1.1. gmp

从官网(https://gmplib.org/download/gmp/)下载最新的源码包:

wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz

解压:

tar -xvf gmp-6.3.0.tar.xz

进入解压后的文件夹:

cd gmp-6.3.0

编译:

./configure
make -j16
sudo make install

返回上一级目录:

cd ..
1.2.2.1.2. mpfr

从官网(https://www.mpfr.org/)下载最新的源码包:

wget https://www.mpfr.org/mpfr-4.2.1/mpfr-4.2.1.tar.xz

解压:

tar -xvf mpfr-4.2.1.tar.xz

进入解压后的文件夹:

cd mpfr-4.2.1

编译:

./configure
make -j16
sudo make install

返回上一级目录:

cd ..
1.2.2.1.3. mpc

从官网(https://ftp.gnu.org/gnu/mpc/)下载最新的源码包:

wget https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz

解压:

tar -zxvf mpc-1.3.1.tar.gz

进入解压后的文件夹:

cd mpc-1.3.1

编译:

./configure
make -j16
sudo make install

返回上一级目录:

cd ..
1.2.2.2. 安装

从官网镜像(http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/)下载v12的源码包:

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-12.4.0/gcc-12.4.0.tar.gz

解压:

tar -zxvf gcc-12.4.0.tar.gz

进入解压后的文件夹:

cd gcc-12.4.0

编译:

./configure --disable-multilib
make -j16
sudo make install

编译完成后查看版本号:

gcc -v

返回上一级目录:

cd ..

1.3. libev >= 4.11(备用)

如果不能apt安装libev的版本不满足要求,则可参考该方法。本节参考来源为Libev中文手册。

1.3.1. 安装

从官网下载源码包:

wget https://libev.cn/downloads/libev-4.33.tar.gz

解压:

tar -zxvf libev-4.33.tar.gz

进入解压后的文件夹:

cd libev-4.33

编译:

sh autogen.sh
./configure
make && sudo make install

1.3.2. 测试

返回上一级目录:

cd ..

新建main.c文件:

vim main.c

内容如下:

#include <stdio.h>
#include <ev.h>

static ev_idle idle;

static void idle_cb(struct ev_loop* loop, ev_idle *idle, int revents) {
  puts("idle start.");
  ev_idle_stop(loop, idle);
}

int main(int argc, char const *argv[])
{
  struct ev_loop* loop = EV_DEFAULT;

  // Register an idle event.
  ev_idle_init(&idle, idle_cb);
  ev_idle_start(loop, &idle);

  ev_run(loop, 0);
  return 0;
}

编译main:

cc -o main main.c -L/usr/local/lib -I/usr/local/include/ -lev -Wl,-rpath,/usr/local/lib

运行main:

./main

输出"idle start."证明安装成功。

1.4. nghttp3

克隆源代码仓库:

git clone --recursive https://github.com/ngtcp2/nghttp3

进入源代码目录:

cd nghttp3

编译:

autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only
make -j$(nproc) check
make install

返回上一级目录:

cd ..

1.5. ngtcp2 build with wolfSSL

1.5.1. wolfSSL >= 5.7.0

构建ngtcp2中的样例文件需要至少一种TLS库,这里使用的是wolfSSL。

克隆源代码仓库:

git clone --depth 1 -b v5.7.4-stable https://github.com/wolfSSL/wolfssl

进入源代码目录:

cd wolfssl

编译:

autoreconf -i
./configure --prefix=$PWD/build --enable-all --enable-aesni --enable-harden --enable-keylog-export --disable-ech
make -j$(nproc)
make install

返回上一级目录:

cd ..

1.5.2. ngtcp2

克隆源代码仓库(翻墙非必须):

git clone --recursive https://github.com/ngtcp2/ngtcp2

--recursive参数用于下载项目中的子项目。
ngtcp2需要两个子项目:munit和urlparse,将分别下载到tests/和third-party/下。
在这里插入图片描述urlparse也需要两个子项目:munit和http-parser,将分别下载到主目录下。
在这里插入图片描述正常情况下,所有子模块都应检出:
在这里插入图片描述在这里插入图片描述如果任何一个子模块下载失败,例如:
在这里插入图片描述解决方法是删除已下载的项目:
rm -r -f ngtcp2
重新克隆源代码仓库,直到一切正常。

进入源代码目录:

cd ngtcp2

编译:

autoreconf -i
./configure PKG_CONFIG_PATH=$PWD/../wolfssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig --with-wolfssl
make -j$(nproc) check

编译成功后在examples中会多出两个二进制文件wsslclient和wsslserver,它们使用HTTP/3。此外,还有两个二进制文件h09wsslclient和h09wsslserver,它们使用HTTP/0.9。

./examples/wsslclient -h
./examples/wsslserver -h

如果运行wsslclient和wsslserver时出现如下问题:
error while loading shared libraries: libev.so.4: cannot open shared object file: No such file or directory
在这里插入图片描述原因是在安装libev时,默认安装在/usr/local/lib中,而二进制文件在/usr/lib中找不到该库。解决方案是重新编译libev,指定安装路径:
cd ~/libev-4.33
sh autogen.sh
./configure --prefix=/usr
sudo make && sudo make install

1.5.3. 使用

1.5.3.1. server

进入wsslserver所在目录:

cd ~/ngtcp2/examples

为服务端生成私钥和证书:

openssl genrsa -out server.key 2048
openssl req -new -x509 -key server.key -out server.crt -days 3650

启动服务端:

./wsslserver 192.168.202.129 4433 server.key server.crt

之后服务端就会在对应端口监听请求,注意输出Using document root /home/csb2/ngtcp2/examples/,说明服务端是以当前目录为文件的根目录。

1.5.3.2. client

进入wsslclient所在目录:

cd ~/ngtcp2/examples

启动客户端,下载由URL指定的文件:

./wsslclient --download=./ 192.168.202.129 4433 https://192.168.202.129:4433/clash.tar.gz

这里URI中的路径是服务端根目录的相对路径。

1.6. ngtcp2 build with LibreSSL(可选)

这里使用LibreSSL库而非wolfSSL。

1.6.1. LibreSSL

克隆源代码仓库(翻墙非必须):

git clone --depth 1 -b v4.0.0 https://github.com/libressl/portable.git libressl

进入源代码目录:

cd libressl

编译:

export LIBRESSL_GIT_OPTIONS="-b libressl-v4.0.0" #必须,不然下一步会报错
./autogen.sh
./configure --prefix=$PWD/build
make -j$(nproc) install

返回上一级目录:

cd ..

1.6.2. ngtcp2

进入源代码目录:

cd ngtcp2

编译:

autoreconf -i
./configure PKG_CONFIG_PATH=$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../libressl/build/lib/pkgconfig
make -j$(nproc) check

编译成功后在examples中会多出两个二进制文件qtlsclient和qtlsserver。

1.7. Wireshark

使用apt命令安装Wireshark:

sudo add-apt-repository universe
sudo apt install wireshark

安装过程中会询问是否允许非超级用户捕获数据包,选择yes。

将当前用户添加到 wireshark 组:

sudo usermod -aG wireshark $(whoami)

在服务端所在的虚机上打开Wireshark,点击“编辑-首选项”。

设置QUIC UDP端口为服务端启动时的端口:

在这里插入图片描述
设置TLS的(Pre)-Master-Secret log filename为examples中的sslkeylog.log:

在这里插入图片描述

选择正确的网络接口(即,服务端IP所在的网卡),设置过滤器:

udp.port==4433

点击“开始捕获分组”即可抓包。


二、HTTP3测试 in CentOS8.5

名称操作
pkg-config >= 0.20yum install pkg-config && pkg-config --version
autoconfyum install autoconf
automakeyum install automake
libtoolyum install libtool
makeyum install make
gcc-11 / g+±11yum install -y gcc-toolset-11 && source /opt/rh/gcc-toolset-11/enable && gcc -v
libev-dev详见1.3节
nghttp3详见1.4节
wolfSSL详见1.5.1节
ngtcp2详见1.5.2节

相关文章:

  • 新一代ITSM:燕千云重构企业智慧服务生态体系
  • 关于spark在yarn上运行时候内存的介绍
  • 计算机组成原理的学习day01
  • 【面试题】利用Promise实现Websocket阻塞式await wsRequest() 请求
  • 关于我对接了deepseek之后部署到本地将数据存储到mysql的过程
  • 卷积神经网络 - 微步卷积、空洞卷积
  • git 基本操作命令
  • Vue3 其它API readonly和shallowreadonly
  • 阿里云国际站代理商:如何通过并行文件系统提升IO性能?
  • CentOS 7 源码安装libjsoncpp-1.9.5库
  • vue3 vue-router 传递路由参数
  • Redis数据持久化机制 + Go语言读写Redis各种类型值
  • vue路由缓存问题
  • Linux MariaDB部署
  • Openssl自签证书相关知识
  • 技术改变生活的10种方式
  • 存储服务器是指什么
  • Java 8 代码重构实战之四 Lambda表达式重构工厂模式与责任链模式
  • JVM - 类加载相关
  • 做一个多级动态表单,可以保存数据和回显数据
  • 网站表单功能/软文发稿公司
  • 网站上的聊天框怎么做的/东莞企业网站排名
  • 一个服务器怎么做两个网站/广州头条新闻最新
  • 建一个个人网站/网络营销推广价格
  • 建站需求/seo网站关键词优化快速官网
  • wordpress自动填写表格/常州百度关键词优化