这是一个聊天室的服务器端。问题是:当启动此线程后,控制器就失去了作用,无法工作,怎样才能在点击控制器时,让服务器关闭(其实是关闭线程)。谢谢各位了,本人菜鸟。
详细代码如下:
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Server extends Frame  implements ActionListener{
private Button BonY;
private Button BonN;
public Server(){
super("控制器");
this.setSize(320,120);
this.setBackground(java.awt.Color.lightGray);
this.setLocation(300,240);
this.setLayout(new java.awt.FlowLayout(FlowLayout.LEFT));
BonY=new Button("启动");
BonN=new Button("关闭");
this.add(BonY);
this.add(BonN);
BonY.addActionListener(this);
BonN.addActionListener(this);
this.addWindowListener(new WinClose());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e){
   if(e.getSource()==BonY)
   {
   new  ChatServer();
   if(e.getSource()==BonN){
  
    new WinClose();
  
   }
        //实例化一个ChatServer类
   }
  
   }
  
public static void main(String arg[]){
  new Server();
}
  
    }
class WinClose implements WindowListener{
  public void windowClosing(WindowEvent e)
  {
   System.exit(0);
   }
 public void windowOpened(WindowEvent e){}
public  void windowClosed(WindowEvent e){}
public  void windowIconified(WindowEvent e){}
public  void windowDeiconified(WindowEvent e){}
public  void windowActivated(WindowEvent e){}
public  void windowDeactivated(WindowEvent e){}
}
class ChatServer { static int Port=6000;  //端口号
   static Vector Clients=new Vector(10);   //存储连接客户信息
   static ServerSocket SvSocket=null;    //建立服务器socket
   static Socket socket=null;   //套接字连接   public ChatServer() {
try {
   System.err.println("服务器启动");
     SvSocket=new ServerSocket(Port);    //初始化服务器套接字
while(true){
     socket=SvSocket.accept();   //等待连接
     System.err.println(socket.getInetAddress()+"连接\n"); //得到客户机地址
     Client client=new Client(socket);  //实例化一个客户线程
    Clients.addElement(client);  //增加客户线程到向量中
    client.start();   //启动线程
NfChatRoom();   //监视聊天室连接变化
}
}
catch(Exception ex) {
     ex.printStackTrace(); //输出出错信息
}
   }   public static void NfChatRoom() {
StringBuffer newUser=new StringBuffer("newUser");
  for(int i=0;i<Clients.size();i++){
      Client c=(Client)Clients.elementAt(i);
  newUser.append(":"+c.name); //客户端姓名字符串
  }
  newUser.append(":"+"所有人");
  SdClientMsg(newUser);   //发送信息到客户端
   }   public static void SdClientMsg(StringBuffer message){
      for(int i=0;i<Clients.size();i++){
      Client client=(Client)Clients.elementAt(i); //分别得到每个客户端的连接
  client.send(message);  //发送信息
  }
   }   public static void SdSlClient(StringBuffer msge,String Name){
   for(int i=0;i<Clients.size();i++){
   Client client=(Client)Clients.elementAt(i);
   if(client.name.equals(Name)){
   client.send(msge);
   }   }
   }
     public void closeAll() {   //关闭所有连接
      while(Clients.size()>0) {   //遍历整个Vector
Client client=(Client)Clients.firstElement();  //得到一个客户端
  try{
      client.socket.close(); //关闭端口
  }
  catch(IOException ex){
      ex.printStackTrace(); //输出错误信息
  }
    Clients.removeElement(client); //移出客户端信息
}
}
  
  public static void disconnect(Client c){     //断开客户端
try{
  System.err.println(c.ip+"断开连接q\n");
      c.send(new StringBuffer("Quit"));   //向客户发送断开连接信息
  c.socket=null; //关闭端口
  }
  catch(Exception ex){
     ex.printStackTrace();
  }
    Clients.removeElement(c);   //移出客户端信息
   } 
  
      class Client extends Thread  {
    Socket socket;    //连接端口
String name;   //用户姓名
String ip;    //客户端IP地址
  BufferedReader reader ;  //输入流
PrintStream ps;   //输出流 public  Client(Socket s){
   socket=s;
   try{
       reader = new BufferedReader(new InputStreamReader(s.getInputStream())); //得到输入流
   ps=new PrintStream(s.getOutputStream());     //得到输出流
   String info=reader.readLine();   //读取接受到的信息
   StringTokenizer stinfo=new StringTokenizer(info,":");  //分解字符串
   String head=stinfo.nextToken();    //获取关键字
           if(stinfo.hasMoreTokens())
    name=stinfo.nextToken();     //获取昵称
   if(stinfo.hasMoreTokens())
    ip=stinfo.nextToken();    //获取IP地址
   }
   catch(IOException ex){
       ex.printStackTrace();
   }
} public void send(StringBuffer msg) {
   ps.println(msg);   //输出信息
   ps.flush();
} public void run(){
    while(true){
        String line=null;
    try{
      line=reader.readLine();  //读取数据流
    }
    catch(IOException ex){
       ex.printStackTrace(); //输出错误信息
   ChatServer.disconnect(this); //断开连接
   ChatServer.NfChatRoom(); //更新信息
   return;
    }     if(line==null){    //客户离开
   ChatServer.disconnect(this);
   ChatServer.NfChatRoom();
   return;
}     StringTokenizer st=new StringTokenizer(line,":"); //分解字符串
    String keyword=st.nextToken();     if(keyword.equals("Connect")){  //发送来的是聊天信息
        StringBuffer msg=new StringBuffer("Connect:");
    msg.append(name);  //在信息上增加用户名
    msg.append(st.nextToken("\0"));
    ChatServer.SdClientMsg(msg);      //发送聊天语句到各个客户端
    }
    else if(keyword.equals("ConnectSl")){
    String SlName = st.nextToken();
    String SlMsg = st.nextToken("\0");
    StringBuffer msg=new StringBuffer("Connect:");
    msg.append(name+" 对你说");
    msg.append(SlMsg);
    ChatServer.SdSlClient(msg,SlName);
    StringBuffer msg1=new StringBuffer("Connect:");
    msg1.append("你对 "+SlName+" 说");
    msg1.append(SlMsg);
    ChatServer.SdSlClient(msg1,name);
    }
    else if(keyword.equals("Quit")){  //退出命令
                 
                    ChatServer.disconnect(this);   //断开连接
    ChatServer.NfChatRoom();   //刷新信息
}
}
}
}


}

解决方案 »

  1.   

    你的线程 一直在阻塞在accept 那里,
      

  2.   

    JAVA中关闭一个线程没有直接的方法调用,以前有个过时的不推荐使用,一般线程执行完run方法的程序后会自动关闭,利用这个特点,如果run方法有循环处理,则不要直接写成
    while(true),写成while(isrunning).需要关闭的时候,将isrunning置为false即可
      

  3.   

    socket=SvSocket.accept();  //等待连接 
    这句的前面,加上:
    SvSocket.setSoTimeout(5000);
    然后在程序中设置一个boolean型的标志位。程序写成while(标志位)。
    在你想终止服务的地方,去设置标志位为false。
    这样,你的pg就有机会去验证这个标志了。
    如果这样改的话,你还要做一些异常处理。因为如果连接超时的话,是会抛出异常的。你应该捕获这个异常,然后重新进入循环。
      

  4.   

    给个boolean 的flag变量,做循环,如果要跳出就设置flag为false
      

  5.   

    线程是不能直接关闭的, 可以去interrupt它
      

  6.   

    同意13#的void run(){   while(Thread.currentThread().isInterrupted()){
            // do more work;
       }}其他线程只要调用t.interrupted(),就能将线程t的中断状态置位,然后t线程的run中循环就会结束了。
      

  7.   


    boolean isrunning=true;
    public void windowClosed(WindowEvent e){
         isrunning=false;

    while(isrunning){
           
      }