120 lines
5.1 KiB
Markdown
120 lines
5.1 KiB
Markdown
# 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
|