所以我一直在尝试学习套接字,并试图创建一个简单的聊天应用程序,其中我有2 JFrames
并且每个都连接到套接字,问题是每次我运行{{1 }}
帧开始正确,但当我点击JFrames
套接字开始连接但不让我继续操作时,一切都被阻止从这一点向前,我一直在试图理解,但我卡住了在这里,有什么想法?
我认为我的问题是套接字应该放在他们自己的Threads中,但是我已经看到了其他解决方案,并且看到他们没有实现Threads,或者至少在他们显示的代码中。
- 醇>
我的套接字连接可能不正确。
¿如果使用connect_button
是错误的,是否仍然可以使用这个类来继续这个练习以及我应该使用哪个PrintStream
课程?考虑到我理解bufferedStreams是你想要效率的方法
答案 0 :(得分:1)
Swing不是线程安全的。也就是说,所有UI事件都发生在事件调度线程的上下文中,包括绘制事件。
阻止此线程的任何内容都会阻止EDT处理新事件,从而使您的应用程序看起来像是挂起的。
请查看Concurrency in Swing了解更多详情......
initServerConnector
类的actionPerformed
方法中对Messenger_Controller
的调用正在创建一个新Conector
,即创建ServerSocket
并调用{{1}在它上面,这是一种阻塞方法。这阻止了EDT在返回之前处理新事件。
相反,您应该使用accept
或SwingWorker
来管理Thread
连接和通信。
有关详细信息,请参阅Worker Threads and SwingWorker。
也不应在EDT的上下文之外更新Swing组件。这意味着如果您在处理套接字通信时需要对UI进行更改,则需要将这些更新同步回UI。
如果您使用的是Socket
,则可以使用SwingWorker
/ publish
方法,或者您需要使用process
,这两种方法都会同步回拨到EDT,您可以安全地进行更改......
答案 1 :(得分:0)
您在EDT(事件调度线程)中创建套接字并处理网络流量,因为您在ActionListener
中执行此操作。这是用于绘制应用程序GUI并处理与用户交互的相同线程。
你不应该在EDT中完成冗长的任务,而是为他们开始一个新的线程。
答案 2 :(得分:0)
如果你保留你的GUI线程来进行套接字通信,那肯定会阻塞你的线程(UI)。
所需要的是一些异步或非阻塞方式来进行套接字通信,这不会阻止你的GUI线程。
保持GUI线程独立并独立运行,并通过创建FutureTask
或ForkJoinTask
或Thread
或非阻塞套接字通信来建立套接字连接,一旦收到通信消息,该通信就会更新。< / p>