终端服务器启动、连接和应用程序 - Windows Server

2262 / 2025-09-01 10:04:08 2018世界杯球队

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

原始 KB 数: 186572

Windows 终端服务器初始化

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

控制台(终端服务器键盘、鼠标和视频)会话始终是第一个加载会话,并被视为特殊情况的客户端连接和分配的 SessionID。 控制台会话以普通 Windows NT 系统会话的形式启动,并加载配置的 Windows NT 显示、鼠标和键盘驱动程序。

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

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

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

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

客户端连接

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

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

低加密只会加密从客户端发送到终端服务器的数据包。 此“仅输入”加密用于保护敏感数据的输入,例如用户的密码。 中等加密将加密来自客户端的传出数据包与低级别加密相同,但也会加密从终端服务器返回到客户端的所有显示数据包。 这种加密方法保护敏感数据,因为它通过网络传输以在远程屏幕上显示。 低加密和中等加密都使用具有 40 位密钥的 Microsoft-RC4 算法(经过修改的 RC4 算法)和 40 位密钥。 高加密将双向加密数据包,传入和传出客户端,但会再次使用行业标准 RC4 加密算法和 40 位密钥。 非导出版本的 Windows NT 终端服务器将提供 128 位高级 RC4 加密。

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

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

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

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

运行应用程序

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

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

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

会话断开连接和用户注销

会话断开连接

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

用户注销

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