JAVA聊天室简易版1.0(多线程)
内部类/外部类
内部类 为自己服务
外部类 还要为别的服务
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; TextField tfTxt=new TextField();//只有一行可以写,有一个ACTION TextArea taContent=new TextArea();//标签定义多行的文本输入控件 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(); } public void connect() { try { s=new Socket("127.0.0.1",8888); dos=new DataOutputStream(s.getOutputStream()); System.out.println("connected!"); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void disconnect()//关闭方法 { try{ dos.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(); } } }//内部类 }
server端
import java.net.*; import java.io.*; public class Chatserver { boolean started=false; ServerSocket ss=null;//初始化 public static void main(String[] args) { new Chatserver().start(); } public void start() { try { ss=new ServerSocket(8888);//端口号8888,TCP started=true;//连接上 }catch (BindException e){ System.out.println("端口使用中"); System.exit(0); }catch(IOException e){ e.printStackTrace();//给出方法的调用程序,一直到异常的产生位置 } try{ while(started) { boolean bConnected=false; Socket s=ss.accept(); Client c=new Client(s);//把s传进去 main是静态的,Client是动态的,在静态的方法NEW一个动态的类不行每来一个new一个新的线程 System.out.println("a client connected!"); new Thread(c).start();//让这个线程启动 /*bConnected=true;//接收到对方之后变成true dis=new DataInputStream(s.getInputStream()); while(bConnected){//有东西来就读 String str=dis.readUTF();//阻塞式 System.out.println(str);*/ } //dis.close(); }catch (IOException e) { e.printStackTrace(); }finally{ try { ss.close(); }catch(IOException e){ e.printStackTrace(); } } /*catch (EOFException e){ System.out.println("Client closed!"); } catch (IOException e) { e.printStackTrace(); }finally{ try{ if(dis !=null) dis.close(); //if(s !=null) s.close(); }catch(IOException e1){ e1.printStackTrace(); } }*/ } } class Client implements Runnable{//线程内部类 private Socket s; private DataInputStream dis=null;//每个客户端都保有自己的inputStream; //保留有自己的连接 private boolean bConnected=false; public Client(Socket s){//传递Socket这个属性,构造函数 this.s=s; try { dis=new DataInputStream(s.getInputStream()); bConnected=true;//连上以后等于TRUE } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run(){ //接收到对方之后变成true try{ while(bConnected){//有东西来就读 String str=dis.readUTF();//阻塞式,接受客户端给我的字符串且打印 System.out.println(str); } }catch (EOFException e){ System.out.println("Client closed!"); } catch (IOException e) { e.printStackTrace(); }finally{ try{ if(dis !=null) dis.close(); //if(s !=null) s.close(); }catch(IOException e1){ e1.printStackTrace(); } } } }
Client不变