提问人:Theodore 提问时间:2/28/2023 更新时间:2/28/2023 访问量:54
Java 桌面应用程序,在多个客户端和一个服务器之间具有持续通信。如何正确设置设备之间的通信?
Java desktop application with continuous communication between many clients and one server. How to properly set communication between devices?
问:
我正在创建一个可以通过 Internet 与服务器通信的 javafx 应用程序,我需要澄清一下事情应该如何工作。
我在客户端和服务器之间使用 SSLSocket(以确保一定程度的安全性)。
在客户端和服务器中,我都在运行一个无限的 while 循环,以便它们彼此保持持续的通信。结婚
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
this.socket = (SSLSocket) socketFactory.createSocket(this.host, this.port);
this.socket.setEnabledProtocols(new String[] {"TLSv1.2"});
this.socket.setEnabledCipherSuites(new String[] {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"});
this.writer = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()));
this.reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
...
public void run() {
this.setSocket(); // creates the connection in another thread
try{
while(true){
this.input = this.reader.readLine(); /* problem 2 */
if(this.reader.ready()) { /* problem 1 */
this.input = this.reader.readLine();
System.out.println(this.input +"\n------------------------------------");
}
if(this.output != null) {
// If the writer has a message that is ready to send send it.
System.out.println("writing to server: " + this.output);
this.writer.println(this.output);
this.writer.flush();
this.setOutput(null);
}
}
} catch (IOException e){
e.printStackTrace();
System.out.println("broke");
}
}
现在我注意到这个实现的几个问题,我提出了一些解决方案。
我注意到 BufferedReader.ready() 方法在调用 BufferedReader.readLine() 并且有数据要读取之前不会返回 true。因此,我将 this.reader.readLine() 方法调用移到了 this.reader.ready() 行的正前方。
这导致 while 循环停止并等待 this.reader.readLine() 方法完成读取(它永远不会这样做,因为服务器不会向客户端发送任何数据(至少不是连续的 - 服务器在收到来自客户端的请求后将数据发送到客户端)。通过停止 while 循环,代码永远不会更新输出值,因此无法向服务器发送响应(即使已建立安全连接,也会有效地锁定客户端与服务器通信。
在对这个问题进行了一些简单的阅读后,我决定通过使用 NIO(非阻塞输入输出)通信来解决它,因为我的示例目前使用的是阻塞输入输出通信。但是在浏览了一些示例之后,设置看起来相当复杂,除非绝对必要,否则我不确定是否要花时间学习它。
这让我想到了另一种方法。如果我将 bufferedReader 和 PrintWriter 推到单独的线程上,那么读取器可以处于停止无限 while 循环中而不会阻塞写入器,从而有效地解决问题,同时允许在阻塞 io 设置中连续通信。
现在,在我实施任何这些解决方案之前,我想知道是否有任何理由反对实现 NIO 或只是将阻塞 io 操作推到单独的线程上。
有没有我没有考虑过的另一种方法?在专业环境中哪个更标准?
答: 暂无答案
评论