Go Practical Examples: Guessing Game, CLI Dictionary, and SOCKS5 Proxy

💡 原文中文,约29300字,阅读约需70分钟。
📝

内容提要

本文整理自Go语言实战笔记,依次实现三个项目:猜数字游戏,用随机种子生成1-100秘密数并循环提示大小;命令行词典,通过彩云翻译API发送HTTP请求,用结构体序列化请求、反序列化响应并打印音标与释义;SOCKS5代理,分握手、认证、请求、relay四阶段,用goroutine和context实现双向数据转发。

🔎

延伸解读

运行前必须注意的凭据与安全事项

文章明确提醒:词典案例使用第三方接口,当前可用性及授权方式尚未验证;原笔记中的浏览器令牌和Cookie已移除,运行前需从服务提供方取得合法凭据,并设置环境变量CAIYUN_DICT_TOKEN,切勿将凭据提交到仓库。SOCKS5示例没有认证,仅用于本机学习,请勿作为公网代理部署。这些提醒直接关系到代码能否运行以及使用安全,读者应首先确认。

猜数字游戏中的随机种子与输入处理

文章通过猜数字游戏演示了Go中随机数生成需要初始化种子,否则每次运行会得到相同的随机数序列,通常用时间戳初始化。同时展示了如何用bufio.NewReader读取用户输入,并用strconv.Atoi将字符串转换为整数,以及处理输入错误。这些是Go基础I/O和类型转换的常见模式,对初学者有参考价值。

命令行词典:从curl到结构体序列化

文章介绍了利用浏览器开发者工具复制curl请求,再通过curlconverter.com转换为Go代码的方法,简化了复杂HTTP请求的构造。随后使用结构体与json.Marshal序列化请求体,并用json.Unmarshal反序列化响应。对于返回的复杂JSON,推荐使用oktools.net/json2go生成结构体,避免手动定义字段的繁琐和错误。这些技巧能提升开发效率。

SOCKS5代理的实现要点与限制

文章将SOCKS5代理分为握手、认证、请求、relay四个阶段,并逐步实现。其中认证阶段仅支持无认证方式(0x00),请求阶段解析目标地址和端口,relay阶段使用两个goroutine和context实现双向数据转发。需要注意的是,该示例不支持IPv6,且没有认证机制,仅适用于本机学习,不可用于公网部署。这些限制在文章中有明确说明。

❓

Q&A

Go语言猜数字游戏为什么每次生成的随机数都一样?怎么解决?

因为默认随机种子是固定的,导致每次运行生成相同的随机数序列。解决方法是用时间戳初始化随机种子,例如使用 rand.Seed(time.Now().UnixNano())。

如何用Go语言调用彩云翻译API实现命令行词典?

先通过浏览器开发者工具找到翻译请求,复制为curl命令,再用curlconverter.com转换成Go代码。然后定义请求和响应结构体,用json.Marshal序列化请求体,发送HTTP POST请求,用json.Unmarshal反序列化响应,最后打印音标和释义。注意需要设置环境变量CAIYUN_DICT_TOKEN作为授权令牌。

SOCKS5代理协议的工作流程分为哪几个阶段?

分为四个阶段:握手阶段、认证阶段、请求阶段和relay阶段。握手阶段协商认证方式;认证阶段进行身份验证(示例中为无认证);请求阶段客户端告知目标地址和端口;relay阶段代理服务器转发双向数据。

在Go中实现SOCKS5代理的relay阶段时,如何实现双向数据转发并避免连接提前关闭?

使用两个goroutine分别调用io.Copy进行单向转发,并利用context.WithCancel创建上下文。每个goroutine在复制出错时调用cancel,主函数等待ctx.Done(),这样任意方向出错时才会关闭连接,实现双向转发。

Go语言中处理HTTP响应时,为什么需要defer resp.Body.Close()?

为了避免资源泄露。在Go中,HTTP响应体是一个流,必须手动关闭。defer语句确保在函数返回时关闭响应体,释放相关资源。

如何将JSON字符串快速转换为Go结构体?

可以使用在线工具如oktools.net/json2go,将JSON字符串粘贴进去,即可生成对应的Go结构体代码。对于复杂嵌套结构,可以选择转换嵌套使代码更紧凑。

🏷️

标签

➡️

继续阅读