v0.1.0
grdp — 纯 Go 的 RDP 客户端协议库
本目录是可独立引用的 Go module git.zeroonesoft.cn/golib/rdplib(github.com/nakagami/grdp 的深度 fork,
MIT 许可,保留上游版权),在 nakagami/grdp
(其 fork 自 tomatome/grdp)基础上大幅扩展,
是 webrdp 浏览器客户端与原生诊断工具共用的协议栈。
能力一览(fork 新增/重写部分加粗)
- RDP 6.0+ 连接:NLA/CredSSP(NTLMv2)、TLS、标准安全协商
- 图形:
- 传统位图/orders 管线(位图缓存 V2/Memblt/指针形状)
- RDPGFX(ClearCodec/RFX Progressive/Planar/AVC420/AVC444), H.264 以原始 NAL 或 I420/NV12 平面回调交付(对接 WebCodecs/FFmpeg 均可)
- 动态分辨率(DisplayControl 通道)与会话色深切换
- 输入:扫描码键盘、Unicode 文本输入(中文 IME)、鼠标移动合并
- 剪贴板:文本/图片/HTML/文件复制(含进度回调)
- 音频:rdpsnd + AUDIO_PLAYBACK DVC,三模式(本地/远端/静音)
- 驱动器重定向(rdpdr):宣告/验证/IO 编码、只读文件系统接口 (状态见 ../doc/RDPDR-2.md)
- 连接期自动检测(RTT/带宽测量应答)、并行 MCS 通道加入、 服务器重定向 PDU 处理
- 事件发射器 emission:反射最小化 + 快速路径可摘除(有回归测试)
- 诊断:PDU 录制器、GFX 缓存存储接口
快速开始(原生 Go 调用)
package main
import (
"fmt"
"net"
"github.com/nakagami/grdp"
)
func main() {
client := grdp.NewRdpClient("10.0.0.3:3389", 1280, 800,
func(addr string) (net.Conn, error) { return net.Dial("tcp", addr) })
client.OnError(func(e error) { fmt.Println("err:", e) }).
OnClose(func() { fmt.Println("closed") }).
OnReady(func() { fmt.Println("session ready") }).
OnBitmap(func(bits []grdp.Bitmap) { /* RGBA() / FillRGBA(dst) */ }).
OnH264I420(func(x, y, w, h int, yb []byte, ys, u []byte, us, v []byte, vs int) {
// 送入渲染器/编码器
}).
OnClipboard(func(text string) { /* 远端剪贴板文本 */ }, func() string { return "" })
if err := client.Login("", "administrator", "password"); err != nil {
panic(err)
}
// 输入/分辨率/关闭:
// client.SendUnicodeText("你好"); client.SetResolution(1920, 1080); client.Close()
select {}
}
完整可运行示例:仓库上层 cmd/nativedemo(带带宽/编码统计的诊断客户端,
go run ./cmd/nativedemo -host x -user u -pass p)。
浏览器(WASM/WebSocket)宿主实现:仓库上层根目录 main.go + wasm_transport.go。
回调都在协议栈读循环 goroutine 内触发——回调里不要长时间阻塞, 重活请转交自己的 goroutine。
架构
grdp.RdpClient 门户:配置(链式 Set*/On*) + Login + 生命周期
├─ protocol/x224·tpkt·t125·sec 传输/安全层(MCS 通道、加密;NLA 在 protocol/nla)
├─ protocol/pdu·lic·gcc 虚拟桌面 PDU、能力协商、许可、GCC
├─ plugin/ 虚拟通道框架 + 内置通道
│ ├─ Channels.Register(ChannelTransport) 通道注册
│ └─ rdpsnd cliprdr rdpdr rdpgfx rdpedisp drdynvc
├─ core/ 传输抽象、缓冲池、工具
└─ emission/ 事件发射器
自定义虚拟通道只需实现三个方法(见 plugin/channel.go):
type ChannelTransport interface {
GetType() (string, uint32) // 通道名 + CHANNEL_OPTION_*
Sender(core.ChannelSender) // 栈回调的发送器
Process(s []byte) // 收包
}
构建与测试
go build ./... # 普通 GOOS 即可;WASM 用 GOOS=js GOARCH=wasm
go test ./...
FFmpeg 硬解(可选):-tags h264,依赖 libavcodec ≥3.4(macOS VideoToolbox /
Linux VAAPI 自动启用,软件回退)。纯 Go 构建默认不带 AVC 解码
(但保留 AVC 能力协商与 NAL 回调,解码交给宿主,如浏览器的 WebCodecs)。
发布检查单(fork 注意事项)
- 模块路径当前沿用上游
github.com/nakagami/grdp(可离线构建、自主维护, 经上层 go.modreplace引用)。对外发布前需改为你自己的 module path: 改本目录go.mod的 module 行 + 全部 import 前缀 (sed -i 's|github.com/nakagami/grdp|<你的路径>|g'),与上层仓库无其他耦合。 - 许可证 MIT,上游版权声明见 LICENSE,请保留。
- 已知问题:驱动器重定向在部分 Windows 服务端上被关闭(RDPDR-2), 跟踪见 ../doc/RDPDR-2.md。
上游致谢与相关项目
Languages
Go
98%
Assembly
2%