小弟最近在写一个网上考试系统作毕业设计,是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 重新构造这些对象的完全等价的图形。 好多词不明白,不知道怎么用非常感谢!!!

解决方案 »

  1.   

    将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。可以使用 writeObject 和 readObject 方法重写类的默认序列化。由此对象引用的对象是以可变迁的方式写入的,这样,可以通过ObjectInputStream 重新构造这些对象的完全等价的图形。 
    这些是传的过程,你不用管这些,你只管调用函数就行了。网络能传输什么?文本,二进制。就是能保存在磁盘里的。而对象在哪?对象在内存中。
    所以传输过程就是先把对象保存成文本或二进制,然后传过去。接受端接受以后在恢复成内存中的对象。就是一个序列化反序列化的过程。保存对象的过程:保存对象的类型,然后保存定义对象当前状态的数据。
    读取对象的过程:读取对象类型,创建该类型的一个空白对象,在该空白对象中填充保存在文件中的数据。我们希望磁盘上的对象布局和内存中的对象布局保持一致。在面向对象程序设计中这种情况为"持续性"(persistence).上面是以前记的序列化的笔记。磁盘上的对象布局和内存中的对象布局是理解的关键。
      

  2.   

    1.关闭线程:Thread.currentThread().stop()/destroy();
    2.首先你要明白,在网络上传输(tcp/ip)是不认对象的,只能认二进制的bits,也就是流格式。
    所以用ObjectOutputStream.writeObject 转化成Stream传输,然后用ObjectinputStream.readObject()读取流进行还原。
      

  3.   

    你保证你写出的对象是可序列化的就可以了,也就是实现Serializable接口的类
    你的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;
           }
    }参考下
      

  4.   

    谢谢,但是:
    1.if(e.getActionCommand()=="启动服务器")
    {
    new Thread(new ManagerThread()).start();
    }
    启动了一个新的线程,在新的线程上处理的响应,而Thread.currentThread()是当前的线程,没法关闭刚才启动的那个线程,怎么办啊?
    2.经过两位讲解差不多明白了,只是传数组也和传对象一样吗?
    谢谢
      

  5.   

    重开线程,你的所有对象得重新初始化,这样不太好吧,你那个线程,run方法执行完,线程自动就消
    亡了,垃圾机制自动回回收的,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();
    }
      

  6.   

    在client登录时,以一个唯一的标志(比如IP)当作key,以accept之后建立的socket为data填入到一个hashtable中。
    进行服务的线程中run()中设置一个标志符:while(标志符){……}
    当关闭服务器时把标志符设置为false,然后run方法就会退出,线程也自然结束,之后把服务器关闭服务。
      

  7.   

    先声明个该线程的变量,在全局那里。
    在指定按钮处实例化它
    在关闭处调用STOP
      

  8.   

    if(e.getActionCommand()=="关闭服务器")
    {
     if(t.isAlive())
           t.close();
    }
    在关闭服务器是要注意服务器的资源释放是否会造成client端的死锁
      

  9.   

    ObjectInputStream ois = new ObjectInputStream(s.getInputStream());的时候出现
    java.io.EOFException
    可能是什么原因啊?奇怪啊!弄了一下午了
    而ObjectOutputStream  ois = new ObjectInputStream(s.getInputStream());是正常的!
    高手指点一下
      

  10.   

    刚才这个问题解决了,是server测试时不小心注释掉了
    ois = new ObjectInputStream(s.getInputStream());
    oos = new ObjectOutputStream(s.getOutputStream());
      

  11.   

    java.io.StreamCorruptedException: invalid stream header
    我在传对象的时候出现的,什么原因啊
      

  12.   

    java.io.StreamCorruptedException:   invalid   stream   header     此异常的原因是读取了错误的头信息,如果你去查一下ObjectInputStream的源代码就能看到在构造函数中调用了一个叫做readStreamHeader(),里面检查了留中的头部两个short的常量,那是用于指定用多大的缓存来存放读取的二进制信息的参数,根据jre的版本不同会被适当的改动。