这是一个简单的qq聊天程序,实现了接收和发送数据的功能,先把代码亮一下

/*
 * 服务器端代码

*/
package com.wangweijun.chat;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
public class ChatServer {
 List<Client> clients = new ArrayList<Client>(); public void init() {
  try {
   ServerSocket serverSocket = new ServerSocket(8888);
   // accept()为阻塞性的方法
   while (true) {
    int index = 1;
    Socket socket = serverSocket.accept();
    if (socket != null) {
     System.out.println("a client connected");
     Client client = new Client(socket, index++);
     clients.add(client);
     System.out.println("init  clients size = " + clients.size());
     client.start();
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 } class Client extends Thread {
  int id;
  Socket socket = null;
  DataInputStream dis = null;
  DataOutputStream dos = null;  public Client(Socket socket, int id) {
   this.socket = socket;
   this.id = id;
   try {
    dos = new DataOutputStream(socket.getOutputStream());
    dis = new DataInputStream(socket.getInputStream());
   } catch (IOException e) {
    e.printStackTrace();
   }
  }  @Override
  public void run() {
   // readUTF()为阻塞性的方法
   try {
    while (true) {
     String content = dis.readUTF();
     System.out.println(content);
     //群发
     for (int i = 0; i < clients.size(); i++) {
      Client c = clients.get(i);
      if(!c.equals(this)){
       DataOutputStream dos = c.getDos();
       dos.writeUTF(content);
      }
     }
    }
   } catch (SocketException e) {
    System.out.println("一个客户退出了哈");
   } catch (IOException e) {
    e.printStackTrace();
   } finally {
    try { 
     dis.close();
     dos.close();
     socket.close();
     clients.remove(this);
     System.out.println("clients size = " + clients.size());
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }  public List<Client> getClients() {
   return clients;
  }  public DataOutputStream getDos() {
   return dos;
  }
 } public static void main(String[] args) {
  new ChatServer().init();
 }
} 
/*


 * 客户端代码
 

*/
package com.wangweijun.chat;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;public class ChatClient extends Frame {
 
 TextArea ta = null;
 TextField tf = null;
 
 Socket socket = null;
 DataOutputStream dos = null;
 DataInputStream dis = null;
 
 String content = ""; public static void main(String[] args) {
  new ChatClient().launch();
 }
 
 public void launch(){
  connet();
  this.setTitle("腾讯qq");
  this.setLocation(400, 300);
  this.setSize(300, 400);
  ta = new TextArea();
  tf = new TextField();
  this.add(ta, BorderLayout.NORTH);
  this.add(tf, BorderLayout.SOUTH);
  this.pack();
  this.setVisible(true);
  this.addWindowListener(new WindowAdapter() {
   @Override
   public void windowClosing(WindowEvent e) {
    System.exit(0);
   }
  });
  tf.addActionListener(new TextFieldListener());
  //启动接收线程
  new ReceiverThread().start();
 }
 
 class ReceiverThread extends Thread {
  @Override
  public void run() {
   try {
    while(true){
     String read =  dis.readUTF();
     content = content + read + "/n";
     ta.setText(content);
     System.out.println(read); 
    }
    
   }catch(SocketException e){
    System.out.println("服务器已经停止服务");
    return;
   }catch (IOException e1) {
    e1.printStackTrace();
   }finally{
    try {
     dos.close();
     dis.close();
     socket.close();
    } catch (IOException e1) {
     e1.printStackTrace();
    }
   }
  }
 }
 
 
 private class TextFieldListener implements ActionListener{
  @Override
  public void actionPerformed(ActionEvent e) {
   content = content  + tf.getText() + "/n";
   ta.setText(content);
   send(tf.getText());
   tf.setText("");
  }
 }
 
 public void send(String content){
  try {
   dos.writeUTF(content);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 public void connet(){
  try {
   socket = new Socket("127.0.0.1", 8888);
   dos = new DataOutputStream(socket.getOutputStream());
   dis = new DataInputStream(socket.getInputStream());
  } catch (UnknownHostException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }}

 

经本人测试运行正常,写一点点心得:聊天程序里有几个阻塞性的方法,一个是ServerSocket中的accept(),
接收客户端请求,另一个是DataInputStream中的readUTF(),从客户端读取数据,由于要不断循环的接收客户端请求,接收到客户端请求后,又要不断循环的接收客户端发送过来的数据,所以这两个方法必须处于不同的线程中,我觉得这是本程序的难点