基于Java高级技术实现简单聊天室系统

客户端

public class SQClient {

	private String ip;
	private int port;
	
	public SQClient(String ip, int port) {
		super();
		this.ip = ip;
		this.port = port;
	}

	/**
	 * 进入聊天室
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public void startTalking() throws UnknownHostException, IOException{ 
		Socket s = new Socket(ip,port);
		//启动消息接收线程
		new MsgReceiver(s).start();
		//发送消息
		Scanner sc = new Scanner(System.in);
		String msg = sc.nextLine();
		while(true){
			Utils.sendMsg(s.getOutputStream(), msg);
			if(Objects.equals("/bye", msg)){
				break;
			}
			msg = sc.nextLine();
		}
		
	}
	
	public static void main(String[] args) throws UnknownHostException, IOException {
		SQClient client = new SQClient("*自己的IP地址", 8090);
		client.startTalking();
	}
}

服务端

public class SQServer {
	
	/**服务端口*/
	public static final int PORT = 8090;
	/**存储所有跟其他客户端产生socket对象*/
	public ArrayList sockets = new ArrayList<>();
	
	public void startServer() throws IOException{
		ServerSocket server = new ServerSocket(PORT);
		Utils.msg("SOFTEEM山寨QQ已启动,等待客户端连接..."); 
		while(true){
			//开始循环监听
			Socket s = server.accept();
			if(!Utils.exsists(s, sockets)){
				//将产生的Socket对象存入集合
				sockets.add(s);
				Utils.msg(s.getInetAddress().getHostAddress()+"进入聊天室,当前总数:"+sockets.size());
				//为每一个客户启动聊天服务线程
				new MsgServer(s, sockets).start();
			}else{
				Utils.sendMsg(s.getOutputStream(), "请不要重复进入聊天室!"); 
				s.close();
			}
		}
	}

	public static void main(String[] args) throws IOException {
		new SQServer().startServer();
	}
}

工具类

public class Utils {

	public static void msg(String msg){
		System.out.println(msg);
	}
	
	/**
	 * 将一个字节输入流解析为一个字符串信息并返回
	 * @param is
	 * @return
	 * @throws IOException 
	 */
	public static String getMsg(InputStream is) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = "";
		while((msg = br.readLine()) != null){
			return msg;
		}
		return null;
	}

	/**
	 * 将指定的文本消息通过输出流对象传输到指定的输出源
	 * @param outputStream
	 * @param string
	 */
	public static void sendMsg(OutputStream outputStream, String msg) {
		PrintWriter pw = new PrintWriter(outputStream);
		pw.println(msg);
		pw.flush();
	}
	
	/**
	 * 判断指定的socket是否在集合中存在
	 * @param s
	 * @param list
	 * @return
	 */
	public static boolean exsists(Socket s,ArrayList list){
		//获取当前获取的Socket对象绑定ip地址
		String ip2 = s.getInetAddress().getHostAddress();
		return list.stream().filter(sk->{
						//获取遍历到的其中一个Socket对象绑定的ip
						String ip1 = sk.getInetAddress().getHostAddress();
						return Objects.equals(ip1, ip2);
					}).count() > 0 ;
	}

	
}

接收消息端

public class MsgReceiver extends Thread{

	private Socket s;

	public MsgReceiver(Socket s) {
		super();
		this.s = s;
	}
	
	@Override
	public void run() {
		
		try {
			//从socket中读取消息并解析为字符串
			String msg = Utils.getMsg(s.getInputStream());
			while(true){
				Utils.msg(msg);
				msg = Utils.getMsg(s.getInputStream());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

消息服务端
用于接受所有客户端发送的消息,并且制作N份拷贝转发给其他的客户端

public class MsgServer extends Thread{

	/**当前线程指定的客户端对象*/
	private Socket s;
	/**目前系统中的所有客户端socket*/
	private ArrayList sockets;
	
	public MsgServer(Socket s, ArrayList sockets) {
		super();
		this.s = s;
		this.sockets = sockets;
	}

	@Override
	public void run() {
		try {
			//将socket的输入流解析为文本消息
			String msg = Utils.getMsg(s.getInputStream());
			Date d = new Date();
			DateFormat fmt = DateFormat.getInstance();
			fmt = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]");
			String t = fmt.format(d);
			//循环收发消息
			while(!Objects.equals(msg, "/bye")){
				//Utils.msg(s.getInetAddress().getHostAddress()+":"+msg); 
				//循环遍历所有的Socket对象
				for (Socket sk : sockets) { 
					Utils.sendMsg(sk.getOutputStream(),s.getInetAddress().getHostAddress()+":"+msg+t);
				}
				//将socket的输入流解析为文本消息
				msg = Utils.getMsg(s.getInputStream());
			}
			//退出
			s.close();
			sockets.remove(s);
			Utils.msg("客户端"+s.getInetAddress().getHostAddress()+"退出,目前人数:"+sockets.size()); 
		} catch (IOException e) {
			//e.printStackTrace();
			//将退出的客户移除集合
			sockets.remove(s);
			Utils.msg("客户端"+s.getInetAddress().getHostAddress()+"退出,目前人数:"+sockets.size()); 
		}
	}
}

开启服务端:
基于Java高级技术实现简单聊天室系统_第1张图片
开启客户端:
在这里插入图片描述
发送消息:
基于Java高级技术实现简单聊天室系统_第2张图片

你可能感兴趣的:(代码实现)