Java服务器是否可以在一个端口上同时接受SSL和纯文本连接?

标题说。

如果我尝试将ServerSocket和SSLServerSocket绑定到同一个端口,我会收到错误。 如果客户端尝试连接到不带SSL的SSLServerSocket,则accept()方法会引发错误。 如果客户端尝试通过SSL连接到ServerSocket,我不知道如何建立安全连接。

它甚至可能吗?

您可以接受正常的套接字连接,并在稍后阶段使用SSLSocketFactory.createSocket(Socket s, String host, int port, boolean autoClose) (以及服务器端的SSLSocket.setUseClientMode(false)将其升级到SSL / TLS。

您需要在明文协议中定义一个命令,以便双方都能就发生的升级达成一致(例如,与SMTP或LDAP中的STARTTLS命令类似)。

或者,您可以使用端口统一( 可以使用Grizzly完成 ),从而尝试检测客户端是否使用SSL / TLS客户端Hello消息启动连接。 这可能比较棘手,因为您必须提前读取以检测数据包类型(因此您可能需要保留该缓冲区并将其内容传递到SSLEngine ,而不是直接使用SSLSocket )。