java简易聊天室1.2
系统正在退出
先通知服务器,让服务器该做什么做什么。
停掉线程,监听等一段时间,时间到cut掉
SERVER端
import java.net.*; import java.io.*; import java.util.*; public class Chatserver { boolean started=false;//有没有监听好 ServerSocket ss=null;//初始化 List<Client>clients=new ArrayList<Client>(); public static void main(String[] args) { new Chatserver().start(); } public void start() { try { ss=new ServerSocket(8888);//端口号8888,TCP,监听在8888端口 started=true;//连接上 }catch (BindException e){ System.out.println("端口使用中"); System.exit(0); }catch(IOException e){ e.printStackTrace();//给出方法的调用程序,一直到异常的产生位置 } try{ while(started)//已经启动 { Socket s=ss.accept();//已经启动不断接收客户端的连接 Client c=new Client(s);//接收进来以后起一个线程 System.out.println("a client connected!"); new Thread(c).start();//让这个线程启动,为它服务 clients.add(c); //dis.close(); } }catch (IOException e) { e.printStackTrace(); }finally{ try { ss.close(); }catch(IOException e){ e.printStackTrace(); } } } class Client implements Runnable{//线程内部类 private Socket s;//包装的每个客户端一个单独的Socket,一个半连接 private DataInputStream dis=null;//每个客户端都保有自己的inputStream;从Socket里面赌内容的输入管道 //保留有自己的连接 private DataOutputStream dos=null; private boolean bConnected=false;//是否连上,初始化false public Client(Socket s){//传递Socket这个属性,构造函数 this.s=s;//初始化 try { dis=new DataInputStream(s.getInputStream());//初始化 dos=new DataOutputStream(s.getOutputStream()); bConnected=true;//连上以后等于TRUE } catch (IOException e) { e.printStackTrace(); } } public void send(String str){ try { dos.writeUTF(str); } catch (IOException e) { e.printStackTrace(); } } public void run(){//单独的线程为单独的客户端服务 //接收到对方之后变成true try{ while(bConnected){//有东西来就读 String str=dis.readUTF();//阻塞式,接受客户端给我的字符串且打印 System.out.println(str); for(int i=0;i<clients.size();i++){//集合类 Client c=clients.get(i); c.send(str); System.out.println("发出了一句话"); } /*for(Iterator<Client> it=clients.iterator();it.hasNext();){ Client c=it.next(); c.send(str); }*/ /* Iterator it=clients.iterator(); while(it.hasNext()){ Client c=it.next(); c.send(str); }//内部锁定,没必要 效率低*/ } }catch (EOFException e){ System.out.println("Client closed!"); } catch (IOException e) { e.printStackTrace(); }finally{ try{ if(dis !=null) dis.close(); if(dos !=null) dos.close(); if(s!=null){ s.close(); //s=null; } }catch(IOException e1){ e1.printStackTrace(); } } } } }
Client
import java.awt.*; import java.awt.event.*; import java.io.IOException; import java.net.*; import java.io.*; public class Chatclient extends Frame{ Socket s=null; DataOutputStream dos=null; DataInputStream dis=null; private boolean bConnected =false; TextField tfTxt=new TextField();//只有一行可以写,有一个ACTION TextArea taContent=new TextArea();//标签定义多行的文本输入控件 Thread tRecv=new Thread(new RecvThread()); public static void main(String[] args) { new Chatclient().LaunchFrame(); } public void LaunchFrame() { setLocation(400,300); this.setSize(300,300); add(tfTxt,BorderLayout.SOUTH); add(taContent,BorderLayout.NORTH); pack(); this.addWindowListener(new WindowAdapter(){//关闭窗口 @Override public void windowClosing(WindowEvent e) { disconnect(); System.exit(0); } });//匿名类 tfTxt.addActionListener(new TFListener()); setVisible(true); connect(); //new Thread(new RecvThread()).start(); tRecv.start(); } public void connect() { try { s=new Socket("127.0.0.1",8888); dos=new DataOutputStream(s.getOutputStream()); dis=new DataInputStream(s.getInputStream());//初始化 System.out.println("connected!"); bConnected=true; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void disconnect()//关闭方法 { try{ dos.close(); dis.close(); s.close(); }catch (IOException e){ e.printStackTrace(); } /*try{ bConnected=false;//关闭线程 tRecv.join();//合并 }catch(InterruptedException e){ e.printStackTrace(); }finally{ try{ dos.close(); dis.close(); s.close(); }catch (IOException e){ e.printStackTrace(); } }*/ } private class TFListener implements ActionListener { public void actionPerformed(ActionEvent e) {//一敲回车 String str=tfTxt.getText().trim(); //taContent.setText(str); tfTxt.setText("");//回车之后清空 try { //DataOutputStream dos=new DataOutputStream(s.getOutputStream()); dos.writeUTF(str);//把stream输出去 dos.flush(); //dos.close(); } catch (IOException e1) { e1.printStackTrace(); } } }//内部类 private class RecvThread implements Runnable{ public void run(){ try{ while(bConnected){ String str=dis.readUTF(); System.out.println(str); taContent.setText(taContent.getText()+str+'\n'); } }catch (SocketException e){ System.out.println("退出"); }catch(IOException e){ e.printStackTrace(); } } } }