指定终结点

终结点是用于远程过程调用的服务器进程的网络特定地址。 终结点的实际名称取决于使用的协议序列。 例如,TCP、UDP 和 HTTP 使用端口。 命名管道使用命名管道名称。 客户端/服务器应用程序可以使用已知终结点或动态终结点。 本部分介绍服务器程序用于指定已知和动态终结点的技术。 以下主题中讨论了此信息:

指定已知终结点

当服务器使用已知终结点时,它可以包括终结点数据作为其名称服务数据库条目的一部分。 如果存在,则客户端的绑定句柄包含一个完整的服务器地址,当客户端从服务器条目导入绑定句柄时,该地址包含已知终结点。

服务器程序还可以在指定协议序列的同时指定已知终结点。 调用 RpcServerUseProtseqEpRpcServerUseProtseqEpEx 函数。 两者的区别在于,后一个函数具有服务器可用于控制动态端口分配的额外参数。

如果服务器程序以这种方式指定其终结点信息,则它还应调用 RpcEpRegister 函数以在终结点映射中注册终结点。 即使终结点始终相同,客户端也可以使用终结点映射来查找服务器。

与协议序列一样,应用程序可以在其 IDL 文件中指定终结点信息。 当它这样做时,它应通过调用 RpcServerUseAllProtseqsIfRpcServerUseAllProtseqsIfEx 函数来同时注册协议序列和终结点。 在这种情况下,客户端可以通过 IDL 文件中的接口规范访问终结点信息。 因此,无需调用 RpcEpRegister 函数。

指定动态终结点

动态终结点是服务器开始执行时服务器主机计算机分配的终结点。 大多数服务器应用程序使用动态终结点,以避免与其他程序在服务器主机计算机系统上可用的有限数量的端口上发生冲突。 但是,使用命名管道或 ncalrpc 协议序列的程序具有非常大的终结点名称空间。 与使用其他传输的程序相比,它们从动态终结点中获益更少。

服务器程序在终结点映射数据库中注册动态终结点。 如果希望服务器使用任何可用的终结点,请调用 RpcServerUseAllProtSeqsRpcServerUseAllProtseqsExRpcServerUseProtseqRpcServerUseProtseqEx。 这会将 RPC 运行时库设置为使用所有或一个有效的协议序列 () 动态终结点。 然后,服务器应调用 RpcServerInqBindings 以获取一组有效的绑定句柄。 服务器将绑定句柄或绑定矢量集传递给函数 RpcEpRegister ,以在终结点映射中注册所有合适的终结点。 对于服务器对 RpcEpRegister 进行的每个调用,都应有相应的 RpcBindingVectorFree 调用,以释放绑定向量使用的内存。

请注意,服务器程序可以使用 RpcEpRegisterNoReplace 函数,而不是 RpcEpRegister。 当服务器程序的多个副本必须在服务器主机系统上运行时,程序通常使用 RpcEpRegisterNoReplace

RpcEpRegisterRpcEpRegisterNoReplace 函数将服务器的接口和绑定句柄添加到终结点映射器数据库。 当客户端使用部分绑定句柄进行远程过程调用时,客户端的运行时库会请求服务器计算机的终结点映射器获取兼容服务器实例的终结点。 客户端库提供接口 UUID、协议序列,以及客户端绑定句柄中的对象 UUID(如果存在)。 终结点映射器查找与客户端信息匹配的数据库条目。 客户端/服务器接口 UUID、接口主版本和协议序列必须完全匹配。 此外,服务器的接口次要版本必须大于或等于客户端的次要版本。

如果所有测试都成功,终结点映射器将返回有效的终结点,客户端运行时库将更新绑定句柄中的终结点。

当服务器进程停止运行时,会自动从终结点映射器数据库清除动态终结点。 可以使用 RpcEpUnregister 函数在服务器程序退出之前从终结点映射器数据库中删除终结点,也可以允许自动清理以管理终结点的删除。