java TCP网络编程 聊天室(群聊与私聊)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_42614447/article/details/89875986

java实现简单的聊天系统

效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Service.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * tcp server
 * 
 * tcp服务器
 */
public class Server {

	/**
	 * server
	 *
	 * server
	 */
	private ServerSocket server = null;

	/**
	 * list of client
	 *
	 * 客户列表
	 */
	private List<AClient> list = null;

	public Server() throws IOException {
		System.out.println("Server started...\n服务器已启动...");
		server = new ServerSocket(8888);
		list = new ArrayList<>();
	}

	public void start() {
		while (true) {
			AClient client = new AClient();
			list.add(client);
			new Thread(client).start();
		}
	}

	/**
	 * each Client has a dependant Thread
	 * 
	 * 每个客户端都有一个依赖的线程
	 */
	private class AClient implements Runnable {

		private DataInputStream dis = null;
		private DataOutputStream dos = null;
		private Socket client = null;
		private boolean isRunning = true;
		private String clientName = null;

		public AClient() {
			try {
				client = server.accept();
				dis = new DataInputStream(client.getInputStream());
				dos = new DataOutputStream(client.getOutputStream());
				clientName = dis.readUTF();
				send("Welcome " + clientName + "!\n欢迎 " + clientName + "!");
				officialSendOthers("Welcome " + clientName + " joined us!\n欢迎 " + clientName + " 加入我们!");
			} catch (IOException e) {
				isRunning = false;
				IOUtil.closeAll(dos, dis);
				list.remove(this);
			}
		}

		/**
		 * receive message from client
		 *
		 * 从客户端接收消息
		 * 
		 * @throws IOException
		 */
		public String receive() {
			try {
				return dis.readUTF();
			} catch (IOException e) {
				isRunning = false;
				IOUtil.closeAll(dos, dis);
				list.remove(this);
			}
			return "";
		}

		public void send(String msg) {
			try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				isRunning = false;
				IOUtil.closeAll(dos, dis);
				list.remove(this);
			}
		}

		/**
		 * send message to others
		 *
		 * 向他人发送消息
		 * 
		 * @param msg
		 */
		public void sendOthers(String msg) {
			if (list.size() == 0) {
				send("sorry,there is nobody in this chat room now!\n抱歉,现在聊天室里没有人!");
				return;
			}
			for (AClient a : list) {
				if (a == this) {
					continue;
				}
				a.send(clientName + ":\n" + msg);
			}
		}

		public void officialSendOthers(String msg) {
			for (AClient a : list) {
				a.send(msg);
			}
		}

		public String getClientName() {
			return clientName;
		}

		/**
		 * if the msg is a private conversation
		 *
		 * 如果消息是私人谈话
		 * 
		 * @param msg
		 */
		public boolean privateSession(String msg) {
			String reg = "^@[\u4e00-\u9fa5_a-zA-Z0-9]+ $";
			String msgHead = msg.substring(0, msg.indexOf(" ") + 1);
			if (msgHead.matches(reg)) {
				// target private conversation
				String name = msg.substring(msg.indexOf("@") + 1, msg.indexOf(" "));
				// the content of private conversation
				String sendMsg = msg.substring(msg.indexOf(" ") + 1);
				for (AClient a : list) {
					if (a.getClientName().equals(name)) {
						// send conversation
						a.send(this.getClientName() + ":\n" + sendMsg);
						return true;
					}
				}
				send(name + ":is not online!\n" + name + ":不在线!");
				return true;
			}
			return false;
		}

		@Override
		public void run() {
			while (isRunning) {
				String msg = receive();
				System.out.println("服务器:\n" + msg);
				// private conversation
				if (!privateSession(msg)) {
					sendOthers(msg);
				}
			}
		}

	}

	public static void main(String[] args) {

		try {
			new Server().start();
		} catch (IOException e) {
			e.printStackTrace();
		}

		/*
		 * String msg = "@Rhyme:nihao";
		 * System.out.println(msg.substring(msg.indexOf("@") + 1, msg.indexOf(":")));
		 */
	}
}

Send.java

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * thread of send
 *
 * 发送线程
 */
public class Send implements Runnable {
	/**
	 * outputStream
	 *
	 * 输出流
	 */
	private DataOutputStream dos = null;
	/**
	 * console inputStream
	 *
	 * 控制台输入流
	 */
	private BufferedReader console = null;
	/**
	 * the mark of is thread running well
	 *
	 * 标志是线程运行良好
	 */
	private boolean isRunning = true;

	/**
	 * the name of current client
	 *
	 * 当前客户端的名称
	 */
	private String clientName;

	public Send(Socket client, String name) {
		super();
		try {
			this.clientName = name;
			dos = new DataOutputStream(client.getOutputStream());
			console = new BufferedReader(new InputStreamReader(System.in));
			// send clintName to server
			dos.writeUTF(clientName);
		} catch (IOException e) {
			// when it comes to exception close current thread
			isRunning = false;
			// close input/output streams
			IOUtil.closeAll(dos);
		}
	}

	/**
	 * get message from console
	 *
	 * 从控制台获取消息
	 * 
	 * @return the message is going to be send 消息将被发送出去
	 * @throws IOException
	 */
	public String getMsgFormConsole() {
		try {
			return console.readLine();
		} catch (IOException e) {
			// e.printStackTrace();
			IOUtil.closeAll(console);
		}
		return "";
	}

	/**
	 * send message 发送消息
	 * 
	 * @param msg
	 *            message going to be send 将要发送的消息
	 */
	private void send(String msg) {
		try {
			// make sure the msg is not null and not ""
			if (null != msg && !msg.equals("")) {
				dos.writeUTF(msg);
				dos.flush();
			}
		} catch (IOException e) {
			isRunning = false;
			IOUtil.closeAll(dos);
		}
	}

	@Override
	public void run() {
		while (isRunning) {
			// send message from console
			send(getMsgFormConsole());
		}
	}

}

Receive.java

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * Receiver of tcp client
 *
 * tcp客户端的接收器
 */
public class Receive implements Runnable {

	/**
	 * input stream from the server
	 *
	 * 来自服务器的输入流
	 */
	private DataInputStream dis = null;

	/**
	 * input stream from the server
	 *
	 * 来自服务器的输入流
	 */
	private boolean isRunning = true;

	public Receive(Socket client) {
		super();
		try {
			dis = new DataInputStream(client.getInputStream());
		} catch (IOException e) {
			isRunning = false;
			IOUtil.closeAll(dis);
		}
	}

	/**
	 * receive message from server
	 *
	 * 从服务器接收消息
	 */
	public void receive() {
		try {
			String str = dis.readUTF();
			System.out.println(str);
		} catch (IOException e) {
			isRunning = false;
			IOUtil.closeAll(dis);
		}
	}

	@Override
	public void run() {
		while (isRunning) {
			receive();
		}
	}

}

IOUtil.java

import java.io.Closeable;
import java.io.IOException;

/**
 * util of io close
 */
public class IOUtil {

	public static void closeAll(Closeable... io) {
		for (Closeable i : io) {
			if (null != i) {
				try {
					i.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

Client.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * Client based on tcp protocol
 */
public class Client {
	public static void main(String[] args) {
		try {
			System.out.println("Please enter your nickname!\n请输入您的昵称!");
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String name = br.readLine();

			Socket client = new Socket("localhost", 8888);
			new Thread(new Send(client, name)).start();
			new Thread(new Receive(client)).start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

供参考!

猜你喜欢

转载自blog.csdn.net/weixin_42614447/article/details/89875986