客户端
35 tfTxt.addActionListener(new TFListener()); 光标点在输入框里敲回车的时候-->执行67actionPerformed(ActionEvent e)的方法,改方法把输入的东西发出去,当然再发出去以前要先执行connect.
要退出是先调用30disconnect()这个方法,首先断开连接
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 11 TextField tfTxt=new TextField();//只有一行可以写,有一个ACTION 12 TextArea taContent=new TextArea();//标签定义多行的文本输入控件 13 14 15 public static void main(String[] args) { 16 new Chatclient().LaunchFrame(); 17 } 18 19 public void LaunchFrame() 20 { 21 setLocation(400,300); 22 this.setSize(300,300); 23 add(tfTxt,BorderLayout.SOUTH); 24 add(taContent,BorderLayout.NORTH); 25 pack(); 26 this.addWindowListener(new WindowAdapter(){//关闭窗口 27 28 @Override 29 public void windowClosing(WindowEvent e) { 30 disconnect(); 31 System.exit(0); 32 } 33 34 });//匿名类 35 tfTxt.addActionListener(new TFListener()); 36 setVisible(true); 37 connect(); 38 } 39 40 public void connect() 41 { 42 try { 43 s=new Socket("127.0.0.1",8888); 44 dos=new DataOutputStream(s.getOutputStream()); 45 System.out.println("connected!"); 46 } catch (UnknownHostException e) { 47 e.printStackTrace(); 48 } catch (IOException e) { 49 e.printStackTrace(); 50 } 51 52 } 53 54 public void disconnect()//关闭方法 55 { 56 try{ 57 dos.close(); 58 s.close(); 59 }catch (IOException e){ 60 e.printStackTrace(); 61 } 62 63 64 } 65 private class TFListener implements ActionListener 66 { 67 public void actionPerformed(ActionEvent e) {//一敲回车 68 String str=tfTxt.getText().trim(); 69 taContent.setText(str); 70 tfTxt.setText("");//回车之后清空 71 try { 72 //DataOutputStream dos=new DataOutputStream(s.getOutputStream()); 73 dos.writeUTF(str);//把stream输出去 74 dos.flush(); 75 //dos.close(); 76 } catch (IOException e1) { 77 e1.printStackTrace(); 78 } 79 80 81 } 82 83 }//内部类 84 }
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,监听在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();//让这个线程启动,为它服务 //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 boolean bConnected=false;//是否连上,初始化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(); }catch(IOException e1){ e1.printStackTrace(); } } } }