client
1 import java.awt.*; 2 import java.awt.event.*; 3 import java.io.IOException; 4 import java.net.*; 5 import java.io.*; 6 public class Chatclient extends Frame{ 7 8 Socket s=null; 9 DataOutputStream dos=null; 10 DataInputStream dis=null; 11 private boolean bConnected =false; 12 13 TextField tfTxt=new TextField();//只有一行可以写,有一个ACTION 14 TextArea taContent=new TextArea();//标签定义多行的文本输入控件 15 16 Thread tRecv=new Thread(new RecvThread()); 17 18 public static void main(String[] args) { 19 new Chatclient().LaunchFrame(); 20 } 21 22 public void LaunchFrame() 23 { 24 setLocation(400,300); 25 this.setSize(300,300); 26 add(tfTxt,BorderLayout.SOUTH); 27 add(taContent,BorderLayout.NORTH); 28 pack(); 29 this.addWindowListener(new WindowAdapter(){//关闭窗口 30 31 @Override 32 public void windowClosing(WindowEvent e) { 33 disconnect(); 34 System.exit(0); 35 } 36 37 });//匿名类 38 tfTxt.addActionListener(new TFListener()); 39 setVisible(true); 40 connect(); 41 42 //new Thread(new RecvThread()).start(); 43 tRecv.start(); 44 } 45 46 public void connect() 47 { 48 try { 49 s=new Socket("127.0.0.1",8888); 50 dos=new DataOutputStream(s.getOutputStream()); 51 dis=new DataInputStream(s.getInputStream());//初始化 52 System.out.println("connected!"); 53 bConnected=true; 54 } catch (UnknownHostException e) { 55 e.printStackTrace(); 56 } catch (IOException e) { 57 e.printStackTrace(); 58 } 59 60 } 61 62 public void disconnect()//关闭方法 63 { 64 try{ 65 dos.close(); 66 dis.close(); 67 s.close(); 68 }catch (IOException e){ 69 e.printStackTrace(); 70 } 71 72 73 /*try{ 74 bConnected=false;//关闭线程 75 tRecv.join();//合并 76 77 }catch(InterruptedException e){ 78 e.printStackTrace(); 79 }finally{ 80 try{ 81 dos.close(); 82 dis.close(); 83 s.close(); 84 }catch (IOException e){ 85 e.printStackTrace(); 86 } 87 }*/ 88 } 89 private class TFListener implements ActionListener 90 91 { 92 public void actionPerformed(ActionEvent e) {//一敲回车 93 String str=tfTxt.getText().trim(); 94 //taContent.setText(str); 95 tfTxt.setText("");//回车之后清空 96 try { 97 //DataOutputStream dos=new DataOutputStream(s.getOutputStream()); 98 dos.writeUTF(str);//把stream输出去 99 dos.flush(); 100 //dos.close(); 101 } catch (IOException e1) { 102 e1.printStackTrace(); 103 } 104 105 } 106 107 }//内部类 108 private class RecvThread implements Runnable{ 109 public void run(){ 110 try{ 111 while(bConnected){ 112 String str=dis.readUTF(); 113 System.out.println(str); 114 taContent.setText(taContent.getText()+str+' '); 115 } 116 }catch (SocketException e){ 117 System.out.println("退出"); 118 }catch(IOException e){ 119 e.printStackTrace(); 120 } 121 } 122 } 123 }
Server
1 import java.net.*; 2 import java.io.*; 3 import java.util.*; 4 public class Chatserver { 5 6 boolean started=false;//有没有监听好 7 ServerSocket ss=null;//初始化 8 List<Client>clients=new ArrayList<Client>(); 9 10 public static void main(String[] args) { 11 new Chatserver().start(); 12 } 13 14 public void start() 15 { 16 try { 17 ss=new ServerSocket(8888);//端口号8888,TCP,监听在8888端口 18 started=true;//连接上 19 }catch (BindException e){ 20 System.out.println("端口使用中"); 21 System.exit(0); 22 }catch(IOException e){ 23 e.printStackTrace();//给出方法的调用程序,一直到异常的产生位置 24 } 25 try{ 26 27 while(started)//已经启动 28 { 29 Socket s=ss.accept();//已经启动不断接收客户端的连接 30 Client c=new Client(s);//接收进来以后起一个线程 31 System.out.println("a client connected!"); 32 new Thread(c).start();//让这个线程启动,为它服务 33 clients.add(c); 34 //dis.close(); 35 } 36 37 }catch (IOException e) { 38 e.printStackTrace(); 39 }finally{ 40 try 41 { 42 ss.close(); 43 }catch(IOException e){ 44 e.printStackTrace(); 45 } 46 } 47 48 } 49 50 51 class Client implements Runnable{//线程内部类 52 53 private Socket s;//包装的每个客户端一个单独的Socket,一个半连接 54 private DataInputStream dis=null;//每个客户端都保有自己的inputStream;从Socket里面赌内容的输入管道 55 //保留有自己的连接 56 private DataOutputStream dos=null; 57 private boolean bConnected=false;//是否连上,初始化false 58 public Client(Socket s){//传递Socket这个属性,构造函数 59 this.s=s;//初始化 60 try { 61 dis=new DataInputStream(s.getInputStream());//初始化 62 dos=new DataOutputStream(s.getOutputStream()); 63 bConnected=true;//连上以后等于TRUE 64 } catch (IOException e) { 65 e.printStackTrace(); 66 } 67 } 68 69 public void send(String str){ 70 try { 71 dos.writeUTF(str); 72 } catch (IOException e) { 73 clients.remove(this); 74 System.out.println("对方退出,当前客户端从list里退出"); 75 76 //e.printStackTrace(); 77 } 78 } 79 80 81 public void run(){//单独的线程为单独的客户端服务 82 //接收到对方之后变成true 83 try{ 84 while(bConnected){//有东西来就读 85 String str=dis.readUTF();//阻塞式,接受客户端给我的字符串且打印 86 System.out.println(str); 87 88 for(int i=0;i<clients.size();i++){//集合类 89 Client c=clients.get(i); 90 c.send(str); 91 System.out.println("发出了一句话"); 92 } 93 94 /*for(Iterator<Client> it=clients.iterator();it.hasNext();){ 95 Client c=it.next(); 96 c.send(str); 97 }*/ 98 /* Iterator it=clients.iterator(); 99 while(it.hasNext()){ 100 Client c=it.next(); 101 c.send(str); 102 }//内部锁定,没必要 效率低*/ 103 } 104 }catch(SocketException e){ 105 clients.remove(this); 106 System.out.println("a client quit!"); 107 }catch (EOFException e){ 108 System.out.println("Client closed!"); 109 } 110 catch (IOException e) { 111 e.printStackTrace(); 112 }finally{ 113 try{ 114 if(dis !=null) dis.close(); 115 if(dos !=null) dos.close(); 116 if(s!=null){ 117 s.close(); 118 //s=null; 119 } 120 }catch(IOException e1){ 121 e1.printStackTrace(); 122 } 123 124 } 125 } 126 } 127 }