以下
使用【RdpViewer】称呼共享客户端,【RdpSession】称呼共享服务端
使用【你的程序】称呼共享服务端的启动程序
1、C# RDPSession
添加COM引用 rdpcomapi 1.0 Type Library
C#
session = new RDPSession();
session.OnAttendeeConnected += Session_OnAttendeeConnected;
session.Open();
//对于多对多,也就是当存在多个共享服务端,应使用不通的GroupName,在连接失败需要使用代理连接时才能分辨要连接哪个共享服务端
IRDPSRAPIInvitation invitation = session.Invitations.CreateInvitation(null, "snltty", "snltty", 1024);
string invitationString = invitation.ConnectionString;
//为了能在连接失败后自动连接到代理服务,我们在这里给连接串添加上代理服务器地址
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(invitationString);
XmlElement newLNode = xmlDoc.CreateElement("L");
//假设代理服务地址是192.168.1.18:1803
newLNode.SetAttribute("P", "1803");
newLNode.SetAttribute("N", "192.168.1.18");//我尝试过,rdpviewer不会连接127.0.0.1,请使用局域网IP
xmlDoc.DocumentElement["C"]["T"].AppendChild(newLNode);
invitationString = xmlDoc.OuterXml;
//invitationString 可以把连接串通过各种方式发送给对方
private void Session_OnAttendeeConnected(object pAttendee)
{
//只给查看权限
IRDPSRAPIAttendee attendee = (IRDPSRAPIAttendee)pAttendee;
attendee.ControlLevel = CTRL_LEVEL.CTRL_LEVEL_VIEW;
}
2、aardio RdpViewer
c#可以直接用 RdpViewer控件
C#
import com.lite;
var dll = com.lite("rdpviewerax.dll");
var tsc = dll.createEmbedEx(mainForm,"{32be5ed2-5c86-480f-a914-0ff8885a1b3f}");
tsc.SmartSizing = true;
tsc.DisconnectedText = "正在连接至共享桌面....";
tsc.OnConnectionFailed = function(){
}
tsc.OnConnectionTerminated = function(){
}
//要填写对应的GroupName
tsc.Connect(invitationString,"snltty","snltty");
3、代理流程
代理是如何让RdpViewer和RdpSession形成一条连接,使其成功连接的
- RdpViewer 连接代理,得到一个 socket1,
- 代理去通知你的程序,让它也来连接代理
- 你的程序,与代理连接,得到socket2
- 你的程序,与RdpSession连接,得到socket3
- socket1 和 socket2 和 socket3 之间,交换数据
RdpViewer—socket1—>192.168.1.18:1803<—–socket2<——你的程序—socket3—>RdpSession
3、代理服务
当RdpViewer连接前几个地址都无法连接时,会连接我们添加在最后面的代理服务,我们只需要建立一个这样的服务,等待连接
- 当代理服务收到连接
- 收到第一个数据包,解析出GroupName
- 此时你已经有能力构建出一条完整的连接进行数据交换了
- 加油
解析GroupName的示例代码
C#
private readonly byte[] endBytes = Encoding.UTF8.GetBytes("\r\n");
private readonly byte[] startBytes = Encoding.UTF8.GetBytes("mstshash=");
private bool GetGroupName(Memory<byte> memory, out string groupName)
{
groupName= string.Empty;
int start = memory.Span.IndexOf(startBytes);
if (start < 0) return false;
memory = memory.Slice(start);
int end = memory.Span.IndexOf(endBytes);
if (end < 0) return false;
groupName = Encoding.UTF8.GetString(memory.Span.Slice(startBytes.Length, end - startBytes.Length));
return true;
}