终端服务器演练:启动、连接和应用程序

本文介绍了终端服务器的初始化过程,并介绍了当用户连接到服务器并运行应用程序时发生的情况。

原始产品版本:   Windows Server 2012 R2
原始 KB 数:   186572

Windows 终端服务器初始化

当 Windows 终端服务器启动并加载核心操作系统时,终端服务器服务 ( # A0) 启动,并创建侦听堆栈 (侦听传入连接的每个协议和传输对) 。 将为每个连接分配唯一的会话标识符或 "SessionID",以表示与终端服务器的单个会话。 会话中创建的每个进程都使用关联的 SessionID "标记",以区别于任何其他连接的命名空间中的命名空间。

控制台 (终端服务器键盘、鼠标和视频) 会话始终是第一次加载,并被视为特殊的客户端连接和分配的 SessionID。 控制台会话作为正常的 Windows NT 系统会话启动,并加载了已配置的 Windows NT 显示、鼠标和键盘驱动程序。

然后,终端服务器服务调用 Windows NT 会话管理器 ( # A0) 创建两个 (默认值 = 2) 空闲客户端会话 (在创建了等待客户端连接的控制台会话) 之后。 若要创建空闲会话,会话管理器将执行 ( # A0) 的基于 Windows NT 的客户端/服务器运行时子系统进程,并向该进程分配新的 SessionID。 CSRSS 进程还将在新关联的 SessionID 下调用 Winlogon ( # A0) 进程和 Win32k.sys (窗口管理器和图形设备接口-GDI) 内核模块。 修改后的 Windows NT 映像加载程序将通过图像标头中的预定义位集将此 Win32k.sys 识别为 SessionSpace 可加载图像。 然后,它将图像的代码部分重新定位到物理内存中,其中包含来自该会话的虚拟内核地址空间的指针(如果尚未加载 Win32k.sys)。 按照设计,它将始终附加到以前加载的图像的代码 ( # A0) (如果内存中已经存在)。 例如,从任何活动的应用程序或会话。

然后,将从新创建的 SessionSpace 的 "可分页内核内存" 部分中将此图像的数据 (或非共享) 部分分配给新会话。 与控制台会话不同,终端服务器客户端会话配置为为显示、键盘和鼠标加载单独的驱动程序。

新的显示驱动程序是远程桌面协议 (RDP) 显示设备驱动程序,请 Tsharedd.dll。 鼠标和键盘驱动程序通过多个实例堆栈管理器与堆栈通信,termdd.sys。 Termdd.sys 会将鼠标和键盘活动的邮件发送到 RDP 驱动程序,Wdtshare.sys。 这些驱动程序允许远程可用和交互的 RDP 客户端会话。 最后,终端服务器还将为 RDP 协议调用连接侦听器线程,该线程会再次由多个实例堆栈管理器管理 ( # A0) ,后者侦听 TCP 端口号3389上的 RDP 客户端连接。

此时,CSRSS 进程在其自己的 SessionID 命名空间下存在,并根据需要在每个过程中实例化其数据。 在此 SessionID 中创建的任何进程都将自动在 CSRSS 进程的 SessionSpace 中执行。 这可防止具有不同 SessionIDs 的进程访问其他会话的数据。

客户端连接

可以在任何基于 Windows 的终端 (上安装和运行 RDP 客户端,这取决于 WinCE) 、运行 TCP/IP 32b 的工作组3.11 的 Windows 或基于 Microsoft Win32 API 的平台。 Citrix Metaframe 加载项支持非基于 Windows 的客户端。 Windows for 工作组 RDP 客户端的可执行文件的大小约为 70 KB,使用 300 KB 工作集,并对显示数据使用 100 KB。 基于 Win32 的客户端的大小约为 130 KB,对于显示数据使用 300 KB 工作集和 100 KB。

客户端将通过 TCP 端口3389启动到终端服务器的连接。 终端服务器 RDP 侦听线程将检测会话请求,并创建新的 RDP 堆栈实例以处理新的会话请求。 侦听器线程将把传入会话递交给新的 RDP 堆栈实例,并继续侦听 TCP 端口3389以进行进一步的连接尝试。 在客户端会话连接到会话配置详细信息的句柄协商时,将创建每个 RDP 堆栈。 第一个详细说明将为会话建立加密级别。 终端服务器最初将支持三种加密级别:低、中和高。

"低加密" 将仅对从客户端发送到终端服务器的数据包进行加密。 这种 "仅输入" 加密是为了保护对敏感数据(如用户密码)的输入。 "中等加密" 将从客户端加密传出数据包,与低级加密相同,但也会将从终端服务器返回到客户端的所有显示数据包加密。 此加密方法可保护敏感数据,因为它在网络上传输以在远程屏幕上显示。 低加密和中加密使用 Microsoft RC4 算法 (修改过的 RC4 算法,使用40位密钥改进的性能) 。 高加密会将两个方向的数据包加密到客户端,但将使用业界标准的 RC4 加密算法,并使用40位密钥。 非导出版本的 Windows NT 终端服务器将提供128位的高级别 RC4 加密。

将在客户端和服务器之间交换字体,以确定安装了哪些常见的系统字体。 客户端会将所有已安装的系统字体通知给终端服务器,以便在 RDP 会话期间能够更快地呈现文本。 当终端服务器知道客户端可用的字体时,可以通过将压缩的字体和 Unicode 字符字符串(而不是更大的位图)传递给客户端来节省网络带宽。

默认情况下,所有客户端为位图缓存保留 1.5 MB 内存,用于缓存位图(如图标、工具栏、光标等),但不用于保存 Unicode 字符串。 缓存可通过注册表项进行可调 () 并使用最近使用最少的 (LRU) 算法进行覆盖。 终端服务器还包含用于对客户端启用流控制的屏幕刷新传递的缓冲区,而不是常量 bitstream。 当客户端上的用户交互较高时,将刷新缓冲区大约每秒20次。 在空闲时间期间,或者当没有用户交互时,缓冲区会因每秒刷新10次而变慢。 您可以通过注册表调整所有这些号码。

在会话详细信息已协商之后,此连接的 server RDP 堆栈实例将映射到现有的空闲 Win32k 用户会话,并将通过 Windows NT 登录屏幕提示用户。 如果配置了自动登录,则加密的用户名和密码将传递到终端服务器,然后登录将继续进行。 如果当前不存在空闲的 Win32k 会话,终端服务器服务将调用会话管理器 (SMSS) 为新会话创建新的用户空间。 大部分 Win32k 用户会话都在使用共享的代码,并且在之前加载一个实例后,会显著加快加载速度。

用户键入用户名和密码后,会将数据包加密发送给终端服务器。 然后,Winlogon 进程将执行必要的帐户身份验证,以确保用户具有登录权限,并将用户的域和用户名传递给终端服务器服务,后者将维护域/用户名 SessionID 列表。 如果 SessionID 已与此用户关联 (例如,) 断开连接的会话,则当前活动的会话堆栈将连接到旧会话。 然后,将删除用于初始登录的临时 Win32 会话。 否则,连接将继续正常进行,而终端服务器服务将创建一个新的域/用户名 SessionID 映射。 如果由于某种原因,此用户的多个会话处于活动状态,则会显示会话列表,用户决定选择哪一个会话进行重新连接。

运行应用程序

用户登录后,如果在单应用程序模式下为用户显示) ,则桌面 (或应用程序。 当用户选择要运行的32位应用程序时,鼠标命令将传递给终端服务器,该服务器会将所选的应用程序启动到新的虚拟内存空间 (2 GB 的应用程序,2 GB 内核) 。 只要可能,终端服务器上的所有进程都将在内核和用户模式下共享代码。 为了实现进程之间的代码共享,Windows NT 虚拟内存 (VM) 管理器使用 "写入时复制" 页面保护。 当多个进程想要读取和写入相同的内存内容时,VM 管理器将向内存区域分配写入时复制页面保护。 在执行写入操作之前, (会话的进程) 将使用相同的内存内容,在这种情况下,VM 管理器将把物理页面框架复制到另一个位置,将进程的虚拟地址更新为指向新的页面位置,然后将该页面标记为可读/写。 "写入时复制" 对运行在终端服务器上的应用程序非常有用且效率更高。

当基于 Win32 的应用程序(如 Microsoft Word)通过一个进程 (会话) 加载到物理内存中时,它会被标记为 "写入时复制"。 当新进程 (会话) 也调用 Word 时,图像加载程序将把新的进程指向现有副本 (会话) 到现有副本,因为该应用程序已加载到内存中。 当需要缓冲区和用户特定数据时 (例如,将文件保存到文件) 中,必要的页将被复制到新的物理内存位置,并标记为 (会话) 的单个进程的读/写模式。 VM 管理器将保护此内存空间不会受到其他进程的的。 但是,应用程序的大部分是可共享代码,并且在物理内存中仅有一个代码实例,而不管它是多少次运行的。

(尽管不必要) 在终端服务器环境中运行32位应用程序,但这是最好的方法。 (Win32) 的32位应用程序将允许共享代码并在多用户会话中更高效地运行。 Windows NT 允许16位应用程序 (Win16) 在 Win32 环境中运行,方法是为每个要执行的 Win16 应用程序创建基于虚拟 MS-DOS 的计算机 (VDM) 。 所有16位输出都转换为 Win32 调用,这将执行所需的操作。 由于 Win16 应用程序在自己的 VDM 中执行,因此不能在多个会话中的应用程序之间共享代码。 在 Win16 和 Win32 调用之间进行转换也会消耗系统资源。 在终端服务器环境中运行 Win16 应用程序可能会比基于 Win32 的基于 Win32 的应用程序使用两倍的资源。

会话断开连接和用户注销

会话断开连接

如果用户决定断开会话连接,并且其他进程需要物理内存,则进程和所有虚拟内存空间都将保留并分页到物理磁盘。 由于终端服务器会保留域/用户名及其关联 SessionID 的映射,因此当同一用户重新连接时,将加载现有会话并使其再次可用。 RDP 的另一个优点是,它能够更改会话屏幕分辨率,具体取决于用户对会话的请求。 例如,假设用户之前已连接到处于 800 x 600 分辨率的终端服务器会话并断开连接。 如果用户移至另一台仅支持 640 x 480 分辨率的计算机,并重新连接到现有会话,则将重新绘制桌面以支持新的分辨率。

用户注销

执行注销通常很简单。 用户从会话中注销后,将终止与 SessionID 关联的所有进程,并释放分配给该会话的所有内存。 如果用户运行的是32位应用程序(如 Microsoft Word),并从该会话注销,则应用程序本身的代码将保留在内存中,直到最后一个用户从应用程序退出。