V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cnbatch
V2EX  ›  C++

使用 C++20 协程与 ASIO 库写了个 Socks5 Server 的跨平台 Demo 程序,几乎全功能,单文件源码少于一千行

  •  
  •   cnbatch · 33 天前 · 1812 次点击
    这是一个创建于 33 天前的主题,其中的信息可能已经有所发展或是发生改变。

    源码已经发布在 Github: https://github.com/cnbatch/cpp20-socks5demo

    RFC 1928 要求的功能几乎都实现了。

    支持的功能:

    • IPv4
    • IPv6
    • ‘No Auth’ 认证模式
    • 用户名 / 密码 认证模式
    • TCP Connect
    • TCP BIND
    • UDP Associate

    未实现的功能:

    • GSSAPI 认证模式

    Socks5 标准 (RFC 1928) 写着必须实现这个功能,然而我做的只是个 Demo 程序,平时也用不到 GSSAPI ,为了简单起见就不实现了。

    已在这些系统测试过:

    • Windows 11 + VS2022
    • FreeBSD 13.4
    • FreeBSD 14.2
    • Debian 12

    用协程写代码的体验

    用了协程之后,思路清晰多了,不像 callback 时那么头大,相对而言轻松多了。

    Github 就有一大堆 Socks5 Server 程序,为什么又造了个新的?

    两大原因:

    1. 我自己是 Windows + FreeBSD 用户,正好需要这样的 socks5 server 程序——可以同时在 Windows 与 FreeBSD 运行,能够支持 TCP + UDP, IPv4 + IPv6 ,使用相同的运行配置方式。
      虽然平时 socks5 server 主要在 FreeBSD 当中运行,但稳妥起见也要在 Windows 台式机运行同样的程序,用作 backup 方案。
      最重要的一点,两个平台都要采用 Native 编译方式,而不是单纯的“妥协”编译方式。直白点说就是:

      • Windows 可以用 MSVC 直接编译,不需要经过 Cygwin / MinGW 绕一层。
      • FreeBSD 可以用内置编译器 + BSD Make 直接编译(即使是 cmake 生成的),不需要 GNU Make ,不需要额外再安装编译器。
    2. 一直想试试 ASIO 库的协程模式,毕竟写起来流畅多了。我个人记忆力不太好,callback 数量一多就头大,实在记不过来。趁着有需求,正好拿来试一试。

    小提示

    由于这个程序只是个 Demo ,用是能用。只不过暂时不支持侦听到具体的地址,不提供日志记录,连接超时的时间判断是硬编码的。如果要其他额外功能都实现的话,就不能单靠一个源文件了,只能另开新 repo 把各部份拆开来重新梳理一遍。以后再在新 repo 内慢慢拆、慢慢补。

    7 条回复    2025-03-10 15:54:20 +08:00
    mayli
        1
    mayli  
       33 天前
    的确,socks5 算是最简单实用的 tcp 编程了,要是去掉 ipv6, bind, udp, 还可以更简单。
    aqtata
        2
    aqtata  
       32 天前
    Tab 缩进难受
    nmap
        3
    nmap  
       32 天前
    asio 已经支持协程了吗
    slideclick
        4
    slideclick  
       32 天前
    膜拜
    cnbatch
        5
    cnbatch  
    OP
       32 天前
    @nmap 我记得 2022 年,ASIO 开始支持协程。刚看了下 Github 和作者自己写的 Examples ,应该是在 2021 年 12 月的 1.22.0 开始支持的:
    https://think-async.com/Asio/asio-1.22.0/doc/asio/examples.html
    https://github.com/chriskohlhoff/asio/tree/asio-1-22-0

    我现在才开始用算是有点晚,当然这也是为了等待编译器更新以及作者修 bug
    ASIO 最新版(目前是 1.30.2 )用起来还算顺畅
    cnbatch
        6
    cnbatch  
    OP
       32 天前
    @aqtata 哈哈哈,这是 Eric Allman 风格,原版的 Allman Style 缩进就是 Tab

    我长期用 C# ,习惯了 Allman 缩进方式
    https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions#style-guidelines

    C# 用空格缩进,到了 C++我就索性使用原版 Allman 缩进风格
    WorseIsBetter
        7
    WorseIsBetter  
       32 天前
    毕业后就没怎么写过 C++ 了,几年没关注,现在都已经有原生协程了,有点感慨

    当然以前也可以用 boost.context 之类的实现,只不过语法看上去并不优雅便是了

    ---

    题外话,记得上学那会儿为了练手,搞了个 boost.asio 的 PHP binding ,用 PHP 的 generator 实现的协程:
    https://web.archive.org/web/20201102142032/https://github.com/CismonX/php-asio/wiki/Basic-concepts-of-php-asio#231-generator

    (不过由于水平太菜,做出来的东西性能还不如 AMPHP 之类的纯 PHP 实现,还有内存泄漏的问题不知道该怎么解决,早已删库跑路,哈哈)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   933 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 22:01 · PVG 06:01 · LAX 15:01 · JFK 18:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.