我有一个多线程聊天服务器,我已将其转换为使用 Java SSL 套接字。与我在 Github 上转换的版本相比,您可以看到没有 SSL 套接字的版本。(主分支有 SSL,其他分支有常规套接字)
这个原始模型(没有 SSL)使用由客户端控制的“ServerThreads”通过向服务器端的“ClientThreads”发送消息来与其他客户端通信,然后将它们的消息回显到所有其他 ServerThreads。
这里是ServerThread_w_SSL的run方法(客户端)
@Override
public void run(){
System.out.println("Welcome :" + userName);
System.out.println("Local Port :" + socket.getLocalPort());
System.out.println("Server = " + socket.getRemoteSocketAddress() + ":" + socket.getPort());
//setup handshake
socket.setEnabledCipherSuites(socket.getSupportedCipherSuites());
try{
PrintWriter serverOut = new PrintWriter(socket.getOutputStream(), false);
InputStream serverInStream = socket.getInputStream();
Scanner serverIn = new Scanner(serverInStream);
// BufferedReader userBr = new BufferedReader(new InputStreamReader(userInStream));
// Scanner userIn = new Scanner(userInStream);
socket.startHandshake();
while(!socket.isClosed()){
if(serverInStream.available() > 0){
if(serverIn.hasNextLine()){
System.out.println(serverIn.nextLine());
}
}
原始程序使用常规套接字,但在转换为 SSL 套接字后,我遇到了一个问题:输入没有从 ClientThreads(服务器端)回显到 ServerThreads(客户端)。
在我第一次尝试转换为 SSL 时,我使用了证书、密钥库和信任库。我遇到了同样的问题,就像我在这里没有它们一样,而是只使用依赖于 JDK 附带的 cacerts 文件的默认套接字工厂。
请注意,在遇到此错误之前,要解决的第一个问题是客户端和服务器之间发生的握手失败。由于 SSL 和 Java PrintWriter 类的工作方式,握手在第一次调用 PrintWriter.flush() 时启动,一旦客户端向服务器发送聊天消息,就会发生这种情况。这只能通过在 ClientThread(服务器)和 ServerThread(客户端)中手动启用支持的密码套件来解决,然后至少在 ClientThread 中调用 SSLSocket.StartHandshake(),如果不是同时调用的话。
现在服务器正在接收来自客户端的消息,但它没有将它们回显给客户端。
当我在调试器中运行它并尝试单步执行代码时,我发现 ClientThread 接收客户端的消息并通过为每个 ClientThread 调用 PrintWriter 上的 write() 将其发送回,然后刷新 ()。ServerThread 应该通过调用 InputStream.available() 在不阻塞的情况下检查输入来接收它,但 available() 总是返回“0 字节”,因此它永远不会命中 Scanner.nextLine()
因此 Printwriter.write() 和 .flush() 不发送数据或 InputStream.available() 不读取数据。
森栏
相关分类