# grdp — 纯 Go 的 RDP 客户端协议库 本目录是可独立引用的 Go module `git.zeroonesoft.cn/golib/rdplib`(`github.com/nakagami/grdp` 的深度 fork, MIT 许可,保留上游版权),在 [nakagami/grdp](https://github.com/nakagami/grdp) (其 fork 自 [tomatome/grdp](https://github.com/tomatome/grdp))基础上大幅扩展, 是 [webrdp](../README.md) 浏览器客户端与原生诊断工具共用的协议栈。 ## 能力一览(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 调用) ```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`): ```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.mod `replace` 引用)。**对外发布前需改为你自己的 module path**: 改本目录 `go.mod` 的 module 行 + 全部 import 前缀 (`sed -i 's|github.com/nakagami/grdp|<你的路径>|g'`),与上层仓库无其他耦合。 - 许可证 MIT,上游版权声明见 LICENSE,请保留。 - 已知问题:驱动器重定向在部分 Windows 服务端上被关闭(RDPDR-2), 跟踪见 ../doc/RDPDR-2.md。 ## 上游致谢与相关项目 - 上游取材:[rdpy](https://github.com/citronneur/rdpy)、 [node-rdpjs](https://github.com/citronneur/node-rdpjs)、 [gordp](https://github.com/Madnikulin50/gordp)、 [ncrack_rdp](https://github.com/nmap/ncrack/blob/master/modules/ncrack_rdp.cc)、 [webRDP](https://github.com/Chorder/webRDP) - 相关:https://github.com/nakagami/grdpsdl2 、 https://github.com/nakagami/grdpwasm