这是前段时间写的一个局域网多对多聊天系统,使用socket编程和TCP/IP协议进行数据传输。总体就两个部分,一个是客户端,还有一个是服务器端。其实这个系统编写起来还是很容易的。我这个小程序的亮点就在于:
1、有一个登陆界面;
2、登陆之后进入聊天界面后会有一个服务器的欢迎语句。
在这里给出程序的源代码。
package org.zsl.server; //服务器部分 import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Date; import java.util.List; /* * ChatServer类 服务器 * main() 启动程序入口 * start1() 启动服务器,无线循环等待客户端 * * ServerThread类 实现了Runnable接口 * ServerThread(Socket s) 构造方法 * send() 发送数据给客户端 * run() 覆写方法,接收数据并发送给所有的客户端 * */ public class ChatServer { private static boolean isRun = false; //标识符 private ServerSocket serverSocket = null; //服务器 private Socket client = null; private String name = null; List<ServerThread> st = new ArrayList<ServerThread>(); //st集合用来装产生的服务器线程 public static void main(String[] args) { //启动方法 System.out.println("服务器启动!"); new ChatServer().start1(); } private void start1() { try { serverSocket = new ServerSocket(8888); //实例化服务器,开启端口 isRun = true; //改变标识符 } catch (BindException e) { System.out.println("端口使用中"); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try { while (isRun) { //无限循环 client = serverSocket.accept(); //等待客户端连接,阻塞 ServerThread serverThread = new ServerThread(client); //一个客户端连接产生了一个服务器的线程 st.add(serverThread); //将线程加入结合 name = serverThread.dis.readUTF(); serverThread.setName(name); new Thread(serverThread).start(); //启动线程 for (int i = 0; i < st.size(); i++) { //遍历所有的线程 ServerThread temp = st.get(i); temp.send("<服务器> 欢迎 "+this.name+" 进入聊天室!\n"); //向所有的线程发送信息 } // dis.close(); } } catch (IOException e) { e.printStackTrace(); } finally { try { serverSocket.close(); //关闭服务器 } catch (IOException e) { e.printStackTrace(); } } } class ServerThread implements Runnable { private Socket client; //定义客户端 private DataInputStream dis = null; //定义输入流 private DataOutputStream dos = null; //定义输出流 private boolean bConnected = false; //定义标志位 private boolean flag = true; private String name = null; //定义用户姓名 public String getName() { return name; } public void setName(String name) { this.name = name; } public ServerThread(Socket s) { this.client = 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) { st.remove(this); } } @Override public void run() { try { while (bConnected) { String str = dis.readUTF(); for (int i = 0; i < st.size(); i++) { //遍历所有的线程 ServerThread temp = st.get(i); temp.send("<"+this.name+" "+new Date()+">\n"+" "+str); //向所有的线程发送信息 } } } catch (EOFException e) { System.out.println("client closed"); } catch (IOException e) { e.printStackTrace(); } finally { try { if (client != null) { client.close(); client = null; } if (dis != null) dis.close(); if (dos != null) dos.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } }
package org.zsl.client; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; //登陆界面 public class Register { private JFrame frame = new JFrame("聊天系统登陆界面"); private JLabel lab = new JLabel("请输入姓名:",JLabel.CENTER); private JTextField name = new JTextField(); private JButton submit=new JButton("登陆"); private JButton reset=new JButton("重置"); private String c_name = null; public String getName(){ //取得用户注册姓名 return c_name; } public Register(){ submit.addActionListener(new ActionListener(){ //采用匿名内部类,注册submit的事件监听 public void actionPerformed(ActionEvent arg0){ if(arg0.getSource()==submit){ //判断触发源是否是提交按钮 c_name=name.getText(); new ChatClient(c_name); //将c_name传递到了ChatClient中 frame.dispose(); //关闭本窗口 } } }); reset.addActionListener(new ActionListener(){//注册reset的时间监听 public void actionPerformed(ActionEvent arg1){ if(arg1.getSource()==reset){//这个按钮没有反应 name.setText(""); } } }); frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent arg0){ System.exit(1); } }); frame.setLayout(null); lab.setBounds(25, 50, 100, 50); name.setBounds(135, 60, 150, 30); submit.setBounds(75, 120, 80, 30); reset.setBounds(190, 120, 80, 30); frame.add(lab); frame.add(name); frame.add(submit); frame.add(reset); int width = 350; int high = 240; int w = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2; int h = (Toolkit.getDefaultToolkit().getScreenSize().height - high) / 2; frame.setSize(width, high); frame.setLocation(w, h); frame.setVisible(true); } public static void main(String[] args) { new Register(); } }package org.zsl.client; //客户端部分 import java.awt.Frame; import java.awt.TextArea; import java.awt.TextField; import java.awt.Toolkit; 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.EOFException; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import javax.swing.JButton; import javax.swing.JPanel; public class ChatClient extends Frame { Socket socket = null; TextField inputChat = new TextField(); // 定义文本框用来输入数据 TextArea showChat = new TextArea(); // 展示数据的地方 JButton submit = new JButton("发送"); JPanel pan = new JPanel(); DataInputStream dis = null; // 接收流 DataOutputStream dos = null; // 输出流 private String c_name = null; private static boolean isRun = false; private boolean flag = true; // 让c_name的传递只有一次 public ChatClient() { } public static void main(String[] args) { new ChatClient().launchFrame(); } public ChatClient(String name) { this.c_name = name; this.launchFrame(); } public void launchFrame() { // Swing 界面 this.setTitle("局域网聊天系统"); int width = 510; int high = 360; this.setLayout(null); this.setSize(width, high); showChat.setBounds(5, 5, 490, 295); pan.setBounds(5, 305, 490, 45); pan.setLayout(null); inputChat.setBounds(5, 5, 400, 40); submit.setBounds(405, 5, 95, 40); // 居中地位 int w = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2; int h = (Toolkit.getDefaultToolkit().getScreenSize().height - high) / 2; pan.add(inputChat); pan.add(submit); this.add(showChat); this.add(pan); this.setLocation(w, h); this.setVisible(true); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { disconnect(); System.exit(0); } }); inputChat.addActionListener(new TextFieldListener()); // 输入窗口中添加监听 submit.addActionListener(new TextFieldListener()); // 输入窗口中添加监听 connectToServer(); // 连接服务器 Thread clientThread = new Thread(new ClientThread()); clientThread.start(); // 启动客户端线程 } private void connectToServer() { try { socket = new Socket("125.221.225.105", 8888); dis = new DataInputStream(socket.getInputStream()); dos = new DataOutputStream(socket.getOutputStream()); isRun = true; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void disconnect() { // 如果没连接上服务器则关闭输入输出流和客户端套接字 // 关闭各种流之前必须先关闭接受线程 try { if (dos != null) { dos.close(); } if (dis != null) { dis.close(); } if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } private class ClientThread implements Runnable { @Override public void run() { try { if (flag) { // 启动客户端只传递一次姓名 dos.writeUTF(c_name); flag = false; } while (isRun) { // 无线循环 String str = dis.readUTF(); // 取得服务器端发送的消息 // System.out.println(str); // showChat中的部分由以前的 和 现在的组成 showChat.setText(showChat.getText() + str + '\n'); // 在showChat中显示 } } catch (SocketException e) { System.out.println("bye"); } catch (EOFException e) { } catch (IOException e) { e.printStackTrace(); } } } private class TextFieldListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String s = inputChat.getText().trim(); if (e.getSource() == submit) { if(!("".equals(s))){ // showChat.setText(s); inputChat.setText(""); try { dos.writeUTF(s); dos.flush(); // dos.close(); } catch (IOException e1) { e1.printStackTrace(); } } } else { // showChat.setText(s); inputChat.setText(""); try { dos.writeUTF(s); dos.flush(); // dos.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } }