java-简单的聊天系统(二)

         今天实现一个简单的群聊天系统。

         首先,有一个服务器端,负责接收客户端的消息,并且发送到所有的客户端。

         客户端有发送方法,负责向服务器端发送消息,一个接收消息线程,负责接收服务器端的消息并展示。

         服务器端要有一个数据结构,记住当前在线的所有用户信息(不考虑保存离线消息)(目前用的方法是保存用户登录的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后期集中解决!

猜你喜欢

转载自709002341.iteye.com/blog/2264054