小弟最近在写一个网上考试系统作毕业设计,是cs结构的,在关闭服务器时遇见这样的问题:
启动服务器时,我在ExamServer(界面)上新建一个线程,在这个线程上new了一个ServerManager类,这个类负责和客户端交互信息,在这个类中建了如s,ss,dis,dos,con,stmt等资源,另外在ExamServer(界面)上有个按钮:关闭服务器,我想触发后通过ServerManager中的stop方法(一系列的.close()) 释放刚才那些资源,不知道该怎么办了,因为刚才那个线程找不到了,即使找到了 一个线程调用start()后,在run()方法退出前并发调用那方法将导致start()掷出一个java.lang.IllegalThreadStateException对象。
程序大概是这样的:
public class ExamServer
{
....
....
....
class ExamActionListener implements ActionListener
{
....
....
....
if(e.getActionCommand()=="启动服务器")
{
new Thread(new ManagerThread()).start();
}
if(e.getActionCommand()=="关闭服务器")
{
//这里该怎么写?
}
}
.... class ManagerThread implements Runnable //负责启动服务器的线程
{ public void run()
{
serverManager = new ServerManager(ExamServer.this);
serverManager.create();
}
}
}
public class ServerManager
{
public void create()
{
//这里创建了ss,s,dis,dos,con等资源
}
public void stop()
{
//这里释放了ss,s,dis,dos,con等资源
}
}
小弟弄了好长时间都解决不了,还望高手指教,谢谢!
另外一个问题:
另外,我想在client和server间传数组或对象,怎么传啊?我看到java.io.ObjectOutputStream.writeObject(java.lang.Object)
中:
将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。可以使用 writeObject 和 readObject 方法重写类的默认序列化。由此对象引用的对象是以可变迁的方式写入的,这样,可以通过ObjectInputStream 重新构造这些对象的完全等价的图形。 好多词不明白,不知道怎么用非常感谢!!!
启动服务器时,我在ExamServer(界面)上新建一个线程,在这个线程上new了一个ServerManager类,这个类负责和客户端交互信息,在这个类中建了如s,ss,dis,dos,con,stmt等资源,另外在ExamServer(界面)上有个按钮:关闭服务器,我想触发后通过ServerManager中的stop方法(一系列的.close()) 释放刚才那些资源,不知道该怎么办了,因为刚才那个线程找不到了,即使找到了 一个线程调用start()后,在run()方法退出前并发调用那方法将导致start()掷出一个java.lang.IllegalThreadStateException对象。
程序大概是这样的:
public class ExamServer
{
....
....
....
class ExamActionListener implements ActionListener
{
....
....
....
if(e.getActionCommand()=="启动服务器")
{
new Thread(new ManagerThread()).start();
}
if(e.getActionCommand()=="关闭服务器")
{
//这里该怎么写?
}
}
.... class ManagerThread implements Runnable //负责启动服务器的线程
{ public void run()
{
serverManager = new ServerManager(ExamServer.this);
serverManager.create();
}
}
}
public class ServerManager
{
public void create()
{
//这里创建了ss,s,dis,dos,con等资源
}
public void stop()
{
//这里释放了ss,s,dis,dos,con等资源
}
}
小弟弄了好长时间都解决不了,还望高手指教,谢谢!
另外一个问题:
另外,我想在client和server间传数组或对象,怎么传啊?我看到java.io.ObjectOutputStream.writeObject(java.lang.Object)
中:
将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。可以使用 writeObject 和 readObject 方法重写类的默认序列化。由此对象引用的对象是以可变迁的方式写入的,这样,可以通过ObjectInputStream 重新构造这些对象的完全等价的图形。 好多词不明白,不知道怎么用非常感谢!!!
这些是传的过程,你不用管这些,你只管调用函数就行了。网络能传输什么?文本,二进制。就是能保存在磁盘里的。而对象在哪?对象在内存中。
所以传输过程就是先把对象保存成文本或二进制,然后传过去。接受端接受以后在恢复成内存中的对象。就是一个序列化反序列化的过程。保存对象的过程:保存对象的类型,然后保存定义对象当前状态的数据。
读取对象的过程:读取对象类型,创建该类型的一个空白对象,在该空白对象中填充保存在文件中的数据。我们希望磁盘上的对象布局和内存中的对象布局保持一致。在面向对象程序设计中这种情况为"持续性"(persistence).上面是以前记的序列化的笔记。磁盘上的对象布局和内存中的对象布局是理解的关键。
2.首先你要明白,在网络上传输(tcp/ip)是不认对象的,只能认二进制的bits,也就是流格式。
所以用ObjectOutputStream.writeObject 转化成Stream传输,然后用ObjectinputStream.readObject()读取流进行还原。
你的C/S通过什么通信?Socket吗?那你的服务器端就应该放在一个循环里才对,线程的run方法执行完,这个线程结束了
例如: class ManagerThread implements Runnable //负责启动服务器的线程
{
boolean begin = true;
serverManager = new ServerManager(ExamServer.this);
serverManager.create();
public void run()
{
while(begin)
{
// 你的代码
}
}
public void stop()
{
// 你的代码
begin = flase;
}
}参考下
1.if(e.getActionCommand()=="启动服务器")
{
new Thread(new ManagerThread()).start();
}
启动了一个新的线程,在新的线程上处理的响应,而Thread.currentThread()是当前的线程,没法关闭刚才启动的那个线程,怎么办啊?
2.经过两位讲解差不多明白了,只是传数组也和传对象一样吗?
谢谢
亡了,垃圾机制自动回回收的,public class ExamServer
{
....
....
....Thread t;
public ExamServer()
{
//
//
t = new Thread(new ManagerThread());
}
class ExamActionListener implements ActionListener
{
....
....
....
if(e.getActionCommand()=="启动服务器")
{ if(!(t.isAlive()))
t = new Thread(new ManagerThread());
t.start();
}
进行服务的线程中run()中设置一个标志符:while(标志符){……}
当关闭服务器时把标志符设置为false,然后run方法就会退出,线程也自然结束,之后把服务器关闭服务。
在指定按钮处实例化它
在关闭处调用STOP
{
if(t.isAlive())
t.close();
}
在关闭服务器是要注意服务器的资源释放是否会造成client端的死锁
java.io.EOFException
可能是什么原因啊?奇怪啊!弄了一下午了
而ObjectOutputStream ois = new ObjectInputStream(s.getInputStream());是正常的!
高手指点一下
ois = new ObjectInputStream(s.getInputStream());
oos = new ObjectOutputStream(s.getOutputStream());
我在传对象的时候出现的,什么原因啊