从您的描述中不清楚是否TServerSocket
在端口 8040 上使用 SSL。它对您的设置方式有很大影响TIdMappedPortTCP
。但是,根据您的描述,您至少有向后 的MappedPort
and属性分配。是监听的端口,所以应该是8041。 是连接的端口,所以应该是8040。DefaultPort
DefaultPort
TIdMappedPortTCP
MappedPort
TIdMappedPortTCP
在同一个端口上有未加密和加密的连接并不常见。大多数协议使用单独的端口。这里是这样吗?8040端口是未加密的,8041端口是加密的吗?
如果要TIdMappedPortTCP
在不同的端口上接受加密和未加密的客户端,则需要向TIdMappedPortTCP.Bindings
集合中添加 2 个条目,每个端口一个,并且根本不使用该DefaultPort
属性。在这种情况TIdMappedPortTCP.OnConnect
下,您可以检测客户端连接到哪个端口,然后AThread.OutboundClient
在连接之前进行相应的配置TServerSocket
。
让未加密和加密的客户端连接到同一个端口是不明智的。在这种情况下,您必须嗅探前几个字节以了解客户端是否正在发送 SSL 握手,然后采取相应措施。使用单独的端口更容易。但是,某些协议确实允许客户端连接到未加密的端口,然后在需要时发送命令以激活加密。在这种情况下,您只需要 1 个端口 in TIdMappedPortTCP
,因此您可以定义 1Binding
或使用DefaultPort
.
TIdMappedPortTCP
主要用于在客户端和目标服务器之间来回直接传递原始字节。如果TServerSocket
正在使用 SSL,并且您希望客户端能够正确TServerSocket
使用 SSL ,那么您根本不应该使用。让客户端的原始加密数据按原样传递给,反之亦然。他们应该彼此建立安全会话,而不是与您建立安全会话。如果其中任何一个执行对等身份验证,这一点尤其重要。TIdServerIOHandlerSSL
TIdMappedPortTCP
TServerSocket
如果您需要处理在客户端TServerSocket
与TIdMappedPortTCP
是为了防止)。为此,您必须在客户端和TIdMappedPortTCP
之间TIdMappedPortTCP
以及和之间建立单独的 SSL 会话TServerSocket
。分配TIdServerIOHandlerSSL
给TIdMappedPortTCP
仅有助于与客户端的会话。您必须手动设置会话TServerSocket
。为此,您必须手动将新TIdSSLIOHandlerSocket
对象分配给事件 中的AThread.OutboundClient.IOHandler
属性。不会为你处理。OnConnect
TIdMappedPortTCP
但是,如果TServerSocket
不使用 SSL,并且您将TIdMappedPortTCP
其用作 SSL 网关TServerSocket
,那么您可以跳过OutboundClient.IOHandler
分配,因为您只需要 1 个 SSL 会话,在TIdMappedPortTCP
和客户端之间。
现在,话虽如此,Indy 9 中存在一些问题。TIdSSLIOHandlerOpenSSL.PassThrough
默认情况下该属性为 False(因此假设加密最初是活动的),并TIdServerIOHandlerSSL
假设每个接受的客户端连接都使用 SSL,即使它确实不是。如果未加密的客户端连接到TIdMappedPortTCP
分配TIdServerIOHandlerSSL
,客户端将不会被正确处理。这些问题已在 Indy 10 中修复。但在 Indy 9 中,您将无法在同一TIdMappedPortTCP
组件中处理加密和未加密的客户端。但是,如果您只处理加密的客户端,则不会遇到问题。否则,创建 2TIdMappedPortTCP
组件,一个监听未加密端口,另一个监听加密端口。它们可以共享相同的事件处理程序。如果需要,您可以使用该AThread.Connection.Socket.Binding.Port
属性来了解客户端连接到哪个端口。