我想我会尝试一些简单的尝试来理解Web客户端/服务器应用程序,因为我对此一无所知,但我需要学习。我下载了"邮政编码查询"来自Web(客户端和服务器)的示例。编译它们,一切按宣传方式工作。
然后我在每个表单上删除了一个SSL IO Handler,并将它们指定为处理程序" sslvTLSv1"两者都选中了。现在它没有用。每当我尝试在客户端应用程序中查找邮政编码时,我得到,"错误:1408F10B:SSL例程:SSL3_GET_RECORD:错误的版本号。"我卸载了原始的Indy库并安装了最新版本(10.6.2.5264)。可以肯定的是,我获得了最新的SSL库并将它们放在两个程序文件夹中。
我在Indy看过很多关于SSL的问题和答案,看起来它应该有效。我错过了什么?
这是服务器DFM的相关部分:
object IdTCPServer1: TIdTCPServer
Active = True
Bindings = <
item
IP = '127.0.0.1'
Port = 6000
end>
DefaultPort = 6000
IOHandler = Handler
OnConnect = IdTCPServer1Connect
OnExecute = IdTCPServer1Execute
Left = 32
Top = 24
end
object Handler: TIdServerIOHandlerSSLOpenSSL
SSLOptions.Mode = sslmServer
SSLOptions.VerifyMode = []
SSLOptions.VerifyDepth = 0
Left = 100
Top = 32
end
这是客户DFM的相关部分。
object Client: TIdTCPClient
IOHandler = Handler
ConnectTimeout = 0
Host = '127.0.0.1'
IPVersion = Id_IPv4
Port = 6000
ReadTimeout = -1
Left = 209
Top = 16
end
object Handler: TIdSSLIOHandlerSocketOpenSSL
Destination = '127.0.0.1:6000'
Host = '127.0.0.1'
MaxLineAction = maException
Port = 6000
DefaultPort = 0
SSLOptions.Mode = sslmClient
SSLOptions.VerifyMode = []
SSLOptions.VerifyDepth = 0
Left = 296
Top = 32
end
我添加了将PassThrough设置为false的代码,现在我得到了一个不同的错误。 &#34;错误:14094410:SSL例程:ssl3_read_bytes:sslv3警报握手失败。&#34;
对于那些想要查看源代码的人来说,它位于http://www.atozedsoftware.com/indy/demos/10/index.EN.aspx的网络上(我正在使用服务器的OnExecute版本)。现在唯一的区别是每个单元中的线路设置PassThrough模式。
在服务器代码中:
procedure TformMain.IdTCPServer1Connect(AContext: TIdContext);
begin
TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := False;
AContext.Connection.IOHandler.WriteLn('200 Zip Code Server Ready.');
AContext.Data := TUserData.Create;
end;
在客户端代码中:
procedure TformMain.butnLookupClick(Sender: TObject);
var
i: integer;
begin
butnLookup.Enabled := False; try
lboxResults.Clear;
Handler.PassThrough := False;
答案 0 :(得分:3)
您没有显示任何代码,只显示了您的DFM。这还不够。但我怀疑可能发生的是你在客户端将IOHandler.PassThrough
属性设置为false,但在服务器端没有这样做。
当客户端连接到TIdTCPServer
时,默认情况下服务器不会激活SSL / TLS,因此在决定是否需要SSL / TLS之前,服务器可以分析客户端,甚至可能不安全地与客户端进行通信。这是为了方便服务器在多个端口上侦听,而不是所有端口都使用SSL / TLS(比如HTTP与HTTPS),并处理基于STARTTLS
的协议。
因此,如果您尚未这样做,请确保在连接的两端将IOHandler.PassThrough
设置为false,例如:
Handler.PassThrough := False;
IdTCPClient1.Connect;
procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := False;
end;
如果您确实在两端都这样做,但仍然遇到相同的错误,请确保两端的IOHandler.SSLOptions.SSLMethod
/ IOHandler.SSLOptions.TLSVersions
属性配置正确,并且它们使用的是兼容设置。你说你在两端使用TLSv1,所以你不应该得到错误,除非服务器真的没有使用TLSv1。
答案 1 :(得分:0)
所以,最后我不得不做一些更多的事情,而不是放弃表格上的几个控件。
首先,我必须添加代码以将每个SSL控件的PassThrough属性设置为false(可能它们应该是已发布的属性?)。
然后我必须安装有效的证书并在服务器端设置CertFile,KeyFile和RootCertFile属性。
现在有效!
感谢Remy的帮助,BTW使用的是OpenSSL v1.0.2和Indy 10.5.5。在使用Delphi 2010的Win32(Vista)中。