2

编辑:删除startHandshake();,因为它与问题无关并且很少需要(例如,在我的情况下不是)

我有一个相当具体和罕见的客户端-服务器协议(通过 TCP)。
我已经使用 SSLSocket 实现了它。
现在,我预见我可能需要在未加密的连接上使用相同的协议。

我的问题是实现协议的类有一个字段:(public SSLSocket currentSocket;
然后我的客户端类中的方法会做各种各样的.read(), .write(), flush()...

我考虑过更改字段类型,如下所示:public Socket currentSocket;
但是,问题是我的连接过程不兼容:

public static void connect () {
currentSocket = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
...
  • java.net.Socket 的默认构造函数显然不接受密钥库的东西

我不想仅仅因为这种差异而重新实现我的整个客户......

  • 我的一个想法是,当我需要一个纯文本套接字时,创建一个没有加密的 SSLSocket。
    我不知道这是否是一种专业的方式,或者它是否会起作用(服务器将期望在新用例中使用纯文本客户端套接字)

  • 我的另一个想法是定义两个字段,一个用于纯文本套接字,一个用于 SSL 套接字,然后根据需要使用逻辑将输入/输出流链接到正确的字段。但是,这将导致“挂起”字段。如果您使用 SSL,则会有一个冗余字段Socket plaintextSocket,反之亦然...

有没有办法让我的字段更加抽象,以便我可以在同一个客户端中定义它,然后根据实例化和连接currentSocket的已知变量(类似于 )指示稍微不同的客户端代码路径?needSSLsocket=true

4

1 回答 1

3

SSLSocketextends Socket,因此您可以将SSLSocket对象分配给Socket变量。您将currentSocket字段更改为Socket. 只需SSLSocket在需要时使用另一个变量来处理,例如:

public static void connect () {
    if (needSSLsocket) {
        SSLSocket ssl = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
        ssl.startHandshake();
        ...
        currentSocket = ssl;

        /* or:
        currentSocket = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
        ((SSLSocket) currentSocket).startHandshake();
        ...
        */
    } else {
        currentSocket = new Socket(host, port);
    }
    ...
}
于 2020-01-27T23:41:23.057 回答