嗨,我有一个工作正常的GUI应用程序.我创建了一个套接字服务器 当我在程序中创建Server类的新对象时,GUI应用程序停止响应.
这是我的服务器类.如果我做
Server s = new Server();
在我的主应用程序中它停止工作.我应该如何添加它?制作一个新帖子?我试过了
Thread t = new Thread(new Server()); t.start();
但问题仍然存在.拜托,我将非常感谢你的帮助.
package proj4; import java.net.*; import java.io.*; public class Server implements Runnable { ServerSocket serverSocket = null; Socket clientSocket = null; ObjectOutputStream out = null; ObjectInputStream in = null; int port; static int defaultPort = 30000; boolean isConnected = false; Thread thread; DataPacket packet = null; public Server(int _port) { try { serverSocket = new ServerSocket(_port); serverSocket.setSoTimeout(1000*120); //2 minutes time out isConnected = true; System.out.println("server started successfully"); thread = new Thread(this); thread.setDaemon(true); //thread.run(); } catch (IOException e) { System.err.print("Could not listen on port: " + port); System.exit(1); } try { System.out.println("Waiting for Client"); clientSocket = serverSocket.accept(); System.out.println("Client Connected"); thread.run(); } catch (IOException e) { System.err.println("Accept failed."); System.exit(1); } try { out = new ObjectOutputStream(clientSocket.getOutputStream()); System.out.println("output stream created successfully"); } catch (IOException e) { e.printStackTrace(); } try { in = new ObjectInputStream(clientSocket.getInputStream()); System.out.println("input stream created successfully"); } catch (IOException e) { e.printStackTrace(); } } public Server() { this(defaultPort); //server listens to port 30000 as default } public void run() { System.out.println("Thread running, listening for clients");//debugging purposes while (isConnected) { try { packet = this.getData(); Thread.sleep(0); } catch(InterruptedException e) { e.printStackTrace(); } } } public DataPacket getData() { try { packet = (DataPacket)in.readObject(); } catch (Exception ex) { System.out.println(ex.getMessage()); } return packet; } public void sendData(DataPacket dp) { try { out.writeObject(dp); } catch (IOException e) { e.printStackTrace(); } try { out.flush(); } catch (IOException e) { e.printStackTrace(); } } public void closeConnection() throws IOException { out.close(); in.close(); clientSocket.close(); serverSocket.close(); } }
Eddie.. 11
您的Server
构造函数可能无限期地阻塞accept()
.
关于Swing程序的两件事:
永远不要在Swing事件线程中执行任何长任务,并且,
除非将正在使用的方法明确记录为线程安全,否则永远不要操作Swing事件线程之外的任何Swing对象.
这意味着如果服务器是从Swing事件线程启动的 - 也就是说,如果它是为响应按钮单击等而启动的 - 那么是的,您必须为您的Server对象生成另一个线程.否则,您保证在您的线程退出之前阻止Swing事件线程.
您说即使您为服务器生成另一个线程,您的应用程序仍然停止响应?确保你正在打电话Thread.start()
而不是run()
,或者你不小心通过在自己的线程中运行"新线程"来阻止自己.
笔记:
我看到你Thread.sleep(0);
在run()循环中执行了一个操作.这不能保证做任何事情.如果你有一台CPU机器,这可以公平地实现为无操作,允许同一个线程继续运行.
你真的想isConnected
成为volatile
- 否则不能保证除了改变之外的任何线程都会看到对这个变量的更改.
您不会isConnected
在任何地方设置为false,因此您run()
将一直运行直到JVM停止或直到该线程采用RuntimeException.
不鼓励在构造函数中启动Threads.(参见Java Concurrency In Practice.)
在你使用Thread的方法之前,你不想accept
在你ServerSocket
身上run()
!否则,您的构造函数将阻止等待连接,并且不会将控制权返回给事件线程!
您的构造函数中包含以下代码:
你的代码是:
thread = new Thread(this); thread.setDaemon(true); //thread.run();
当你thread.run()
没有注释掉时,你没有开始新的线程!要做到这一点,你需要这样做thread.start()
.相反,你在调用构造函数的同一个线程中运行这个新的Thread(它永远不会停止,因为上面的原因#3).现在编写代码的方式,所有IOExceptions都会被记录,但是否则会被吞噬.您可能希望设置isConnected
为false
on IOException
,以及in closeConnection()
.
您的Server
构造函数可能无限期地阻塞accept()
.
关于Swing程序的两件事:
永远不要在Swing事件线程中执行任何长任务,并且,
除非将正在使用的方法明确记录为线程安全,否则永远不要操作Swing事件线程之外的任何Swing对象.
这意味着如果服务器是从Swing事件线程启动的 - 也就是说,如果它是为响应按钮单击等而启动的 - 那么是的,您必须为您的Server对象生成另一个线程.否则,您保证在您的线程退出之前阻止Swing事件线程.
您说即使您为服务器生成另一个线程,您的应用程序仍然停止响应?确保你正在打电话Thread.start()
而不是run()
,或者你不小心通过在自己的线程中运行"新线程"来阻止自己.
笔记:
我看到你Thread.sleep(0);
在run()循环中执行了一个操作.这不能保证做任何事情.如果你有一台CPU机器,这可以公平地实现为无操作,允许同一个线程继续运行.
你真的想isConnected
成为volatile
- 否则不能保证除了改变之外的任何线程都会看到对这个变量的更改.
您不会isConnected
在任何地方设置为false,因此您run()
将一直运行直到JVM停止或直到该线程采用RuntimeException.
不鼓励在构造函数中启动Threads.(参见Java Concurrency In Practice.)
在你使用Thread的方法之前,你不想accept
在你ServerSocket
身上run()
!否则,您的构造函数将阻止等待连接,并且不会将控制权返回给事件线程!
您的构造函数中包含以下代码:
你的代码是:
thread = new Thread(this); thread.setDaemon(true); //thread.run();
当你thread.run()
没有注释掉时,你没有开始新的线程!要做到这一点,你需要这样做thread.start()
.相反,你在调用构造函数的同一个线程中运行这个新的Thread(它永远不会停止,因为上面的原因#3).现在编写代码的方式,所有IOExceptions都会被记录,但是否则会被吞噬.您可能希望设置isConnected
为false
on IOException
,以及in closeConnection()
.