今天实现一个简单的群聊天系统。
首先,有一个服务器端,负责接收客户端的消息,并且发送到所有的客户端。
客户端有发送方法,负责向服务器端发送消息,一个接收消息线程,负责接收服务器端的消息并展示。
服务器端要有一个数据结构,记住当前在线的所有用户信息(不考虑保存离线消息)(目前用的方法是保存用户登录的ip(测试用都是localhost)和端口,因为ip一样,所有有一个set,保存所有用户的连接端口即可)
//所有用户的连接端口 private static Set<Integer> chatUsers = new HashSet<Integer>();
服务器端的代码:
package chatSystem; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.HashSet; import java.util.Set; /** * Service : 服务器端 * * @author xuejupo [email protected] create in 2015-12-14 下午3:21:13 */ public class Service { private InetSocketAddress socketAddress = null; // 服务监听地址 private DatagramSocket datagramSocket = null; // 连接对象 //所有用户的连接端口 private static Set<Integer> chatUsers = new HashSet<Integer>(); //服务器端的端口 private static int port = 80; public void init() { socketAddress = new InetSocketAddress("localhost", port); System.out.println("--------服务器端已启动---------"); try { datagramSocket = new DatagramSocket(socketAddress); } catch (SocketException e) { e.printStackTrace(); } byte[] buffer = new byte[1024 * 64]; // 缓冲区 DatagramPacket packet = new DatagramPacket(buffer, buffer.length); while(true){ receive(packet); chatUsers.add(packet.getPort()); this.sendAll(packet); } } public static void main(String[] s){ Service ss = new Service(); ss.init(); } /** * receive: 接收数据包 * @param packet * @return * @throws Exception * DatagramPacket 返回类型 */ public DatagramPacket receive(DatagramPacket packet){ try { datagramSocket.receive(packet); } catch (Exception e) { System.out.println(e.getLocalizedMessage()); } return packet; } /** 将信息发送给客户端 * response: * @param packet * void 返回类型 */ public void send(DatagramPacket packet) { try { datagramSocket.send(packet); } catch (Exception e) { e.printStackTrace(); } } /** * sendAll: 将信息发给所有的在线客户端 * @param packet * void 返回类型 */ private void sendAll(DatagramPacket packet){ for(int iaddr:chatUsers){ try { packet = new DatagramPacket(packet.getData(), packet.getLength(), InetAddress.getByName("localhost"), iaddr); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.send(packet); } } }
客户端代码:
package chatSystem; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.util.Scanner; /** * Client : * * @author xuejupo [email protected] create in 2015-12-14 下午3:47:37 */ public class Client extends Thread { private static final int PORT = 80; private DatagramSocket dataSocket; private DatagramPacket dataPacket; private byte sendDataByte[]; private String sendStr; private int clinePort; private String name; public Client(int clinePort,String name){ this.setName(name); this.clinePort = clinePort; this.name = name; } public void run(){ new receiveThread().start(); this.init(); } public void init() { try { // 指定端口号,避免与其他应用程序发生冲突 dataSocket = new DatagramSocket(clinePort); Scanner sc = new Scanner(System.in); System.out.println("输入聊天信息,exit退出!"); sendStr = sc.nextLine(); while (!"exit".equals(sendStr)) { sendDataByte = new byte[1024]; sendDataByte = (name+"说:"+sendStr).getBytes(); dataPacket = new DatagramPacket(sendDataByte, sendDataByte.length, InetAddress.getByName("localhost"), PORT); this.sendDate(dataPacket); sendStr = sc.nextLine(); } } catch (SocketException se) { se.printStackTrace(); } catch (IOException ie) { ie.printStackTrace(); } } /** * sendDate: 发送数据包 * * @param packet * void 返回类型 */ public void sendDate(DatagramPacket packet) { try { dataSocket.send(packet); } catch (Exception e) { e.printStackTrace(); } } /** * sendDate: 接收数据包 * * @param packet * void 返回类型 */ public void receive(DatagramPacket packet) { try { dataSocket.receive(packet); } catch (Exception e) { e.printStackTrace(); } } //接收服务器端数据的线程 class receiveThread extends Thread{ public void run(){ while(true){ if(dataPacket != null){ receive(dataPacket); System.out.println("群消息:"+new String(dataPacket.getData())); } try { Thread.sleep(5 * 100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
测试程序:
public static void main(String[] args) { // TODO Auto-generated method stub Client c2 = new Client(2312,"老二"); System.out.println(c2.getName()); c2.start(); }
public static void main(String[] args) { // TODO Auto-generated method stub Client c1 = new Client(2337,"老大"); c1.start(); }
结果:服务器端:
--------服务器端已启动---------
客户端1:
输入聊天信息,exit退出! 123123 群消息:老大说:123123 群消息:老二说:123456 群消息:老二说:test22 test11 群消息:老大说:test11 群消息:老二说:test33 群消息:老二说:test44
客户端2:
扫描二维码关注公众号,回复:
716939 查看本文章
老二 输入聊天信息,exit退出! 123456 群消息:老二说:123456 test22 群消息:老二说:test22 群消息:老大说:test11 test33 群消息:老二说:test33 test44 群消息:老二说:test44
PS:基本功能先实现,bug后期集中解决!