简体   繁体   English

Java:如何在“常规”TCP 套接字和 SSLSocket 之间进行抽象

[英]Java: How to abstract between "regular" TCP Socket and SSLSocket

Edit: Removed startHandshake();编辑:删除了startHandshake(); as it's irrelevant to the question and rarely needed (for example, not in my case)因为它与问题无关并且很少需要(例如,不是我的情况)

I have a rather specific and rare client-server protocol (over TCP).我有一个相当具体且罕见的客户端-服务器协议(通过 TCP)。
I've implemented it using SSLSocket.我已经使用 SSLSocket 实现了它。
Now, I foresee that I might need to use the same protocol over an un-encrypted connection.现在,我预见到我可能需要通过未加密的连接使用相同的协议。

My problem is that the class implementing the protocol has a field: public SSLSocket currentSocket;我的问题是实现协议的类有一个字段: public SSLSocket currentSocket;
(and then the methods in my client class do all sorts of .read(), .write(), flush()... ) (然后我的客户端类中的方法执行各种.read(), .write(), flush()...

I thought about changing the field type, like so: public Socket currentSocket;我想过改变字段类型,像这样: public Socket currentSocket;
However, then, the problem is that my connection procedure is incompatible:但是,问题是我的连接程序不兼容:

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

I don't want to re-implement my whole client just for this difference...我不想仅仅因为这种差异而重新实现我的整个客户端......

  • One thought I have is, when I need a plaintext Socket, to create an SSLSocket with no encryption.我的一个想法是,当我需要一个纯文本 Socket 时,创建一个没有加密的 SSLSocket。
    I don't know if that's a professional way of doing it or if it will even work (the server will expect a plaintext client socket in the new use case)我不知道这是否是一种专业的方法,或者它是否可以工作(服务器将期望在新用例中使用纯文本客户端套接字)

  • My other idea is to define two fields, one for plaintext socket, one for SSL socket and then use logic to link the in/out streams to the correct field, as needed.我的另一个想法是定义两个字段,一个用于明文套接字,一个用于 SSL 套接字,然后根据需要使用逻辑将输入/输出流链接到正确的字段。 However, that will result in a "hanging" field.但是,这将导致“悬挂”字段。 If you use SSL, there will be a redundant field Socket plaintextSocket and vice-versa...如果使用SSL,则会有一个冗余字段Socket plaintextSocket ,反之亦然...

Is there a way to make my currentSocket field more abstract, so that I can define it in the same client, then instruct a slightly different client code path depending on a known variable (something like needSSLsocket=true ) for the instantiation and connection?有没有办法让我的currentSocket字段更加抽象,以便我可以在同一个客户端中定义它,然后根据一个已知变量(比如needSSLsocket=true )为实例化和连接指示稍微不同的客户端代码路径?

SSLSocket extends Socket , so you can assign an SSLSocket object to a Socket variable. SSLSocket扩展了Socket ,因此您可以将SSLSocket对象分配给Socket变量。 You are right to change your currentSocket field to a Socket .您将currentSocket字段更改为Socket是正确的。 Simply use another variable to handle the SSLSocket when needed, eg:只需在需要时使用另一个变量来处理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);
    }
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM