服务器端
import java.io.IOException;
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer {
public static int count = 0;
boolean started = false;
ServerSocket ss = null;
List<Client> clients = new ArrayList<Client>();
public static void main(String[] args) {
new ChatServer().startLink();
}
public void startLink() {
try {
ss = new ServerSocket(8888);
started = true; //成功获取一个端口后将started 改为 true
} catch(BindException e) {
System.out.println("ChatServer is running now !");
System.exit(0);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
while(started) {
count++;
Socket s = ss.accept(); //不断地等待接收客户端,注:accept()为阻塞式方法
Client c = new Client(s); // Client 为客户端线程类 ,即将每一个客户端分别交给一个线程处理
clients.add(c); //clients 为ArrayList型类集
new Thread(c,"Chater-"+count).start();
// dis.close();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client implements Runnable { //客户端线程 为内部类
private Socket s;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean bConnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String str) {
try {
dos.writeUTF(str);
} catch (IOException e) {
clients.remove(this);
System.out.println("对方已经退出!");
}
}
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
for(int i = 0; i < clients.size(); i++) {
Client c = clients.get(i);
c.send(" "+Thread.currentThread().getName()+" "+str);
}
}
} catch(EOFException e) { //当输入过程中意外到达文件或流的末尾时,抛出此异常
for(int i = 0; i < clients.size(); i++) {
Client c = clients.get(i);
c.send(" "+Thread.currentThread().getName()+" exited !");
}
System.out.println(" A client exited !");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(dis != null) dis.close();
if(dos != null) dos.close();
if(s != null) s.close();
} catch(IOException e1) {
e1.printStackTrace();
}
}
}
}
}
客户端
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import java.io.*;
import javax.swing.*;
import java.util.Date;
import java.text.DateFormat;
public class ChatClient {
public static void main(String[] args) {
new Clients();
}
}
class Clients extends JFrame {
Socket s = null;
DateFormat df = DateFormat.getDateTimeInstance();
DataOutputStream dos = null;
DataInputStream dis = null;
JSplitPane lfsplit = null;
JSplitPane tbsplit = null;
Thread tRecv = null;
private boolean bConnected = false;
JTextField tfTxt = new JTextField();
JTextArea taContent = new JTextArea(25,60);
Panel panel = new Panel();
String picPath1 = "D://Program Files//Eclipse workspace//Chat1.4//images//mailstar32.png";
String picPath2 = "D://Program Files//Eclipse workspace//Chat1.4//images//stop32.png";
String picPath3 = "D://Program Files//Eclipse workspace//Chat1.4//images//ima.jpg";
Icon icon1 = new ImageIcon(picPath1,"send");
Icon icon2 = new ImageIcon(picPath2,"close");
Icon icon3 = new ImageIcon(picPath3,"Log");
JButton button1 = new JButton(icon1);
JButton button2 = new JButton(icon2);
JButton button3 = new JButton(icon3);
public Clients() {
super(" ★★★★★ iTBa ChatRoom ★★★★★ ");
tRecv = new Thread(new RecvThread());
setLocation(200, 50);
this.setSize(500, 450);
taContent.setBackground(Color.black);
taContent.setForeground(Color.green);
tfTxt.setBackground(Color.LIGHT_GRAY);
panel.setBackground(Color.darkGray);
panel.add(button1,BorderLayout.CENTER);
panel.add(button2,BorderLayout.EAST);
add(panel,BorderLayout.SOUTH);
lfsplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,button3,tfTxt); //左右分块
lfsplit.setDividerSize(1);
tbsplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,new JScrollPane(taContent, //上下分块
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),lfsplit);
tbsplit.setDividerSize(1);
add(tbsplit);
pack();
this.addWindowListener(new WindowAdapter() { // 匿名类实现窗口监视器,关闭窗口
@Override
public void windowClosing(WindowEvent arg0) { //在窗口适配器中可只重写这一个方法
disconnect();
System.exit(0);
}
});
button1.addActionListener(new TFListener());
button2.addActionListener(new TFListener());
tfTxt.addActionListener(new TFListener());
setVisible(true);
connect();
tRecv.start();
}
public void connect() {
try {
s = new Socket("196.105.126.119", 8888);
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
System.out.println("Have linked");
bConnected = true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void disconnect() {
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private class TFListener implements ActionListener {
private boolean isNull = true;
public void actionPerformed(ActionEvent e) {
if(e.getSource() == tfTxt) {
String str = tfTxt.getText().trim();
tfTxt.setText("");
try {
dos.writeUTF(str);
dos.flush();
// dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if(e.getSource() == button1) {
if(!tfTxt.getText().equals("")) {
String str = tfTxt.getText().trim();
tfTxt.setText("");
try {
dos.writeUTF(str);
dos.flush();
// dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
while(isNull) {
String str = " 请不要发送空内容 !";
try {
dos.writeUTF(str);
dos.flush();
isNull = false;
// dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
if(e.getSource() == button2) {
disconnect();
System.exit(0);
}
}
}
private class RecvThread implements Runnable {
public void run() {
try {
while (bConnected) {
String str = dis.readUTF();// 阻塞性语句
taContent.setText(taContent.getText()+df.format(new Date())+"/n"+ " "+str + "/n");//
}
} catch (SocketException e) {
System.out.println("A chater exited!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}