TCP-based chat tool QQ

### Introduction:
Based on JAVA language development of a network chat tool, through the implementation of the TCP Socket programming, the use of multi-threading to achieve a multi-client connections. Imitate Tencent QQ interface, function is relatively simple, but using the most basic network programming, such as socket, tcp, I / O blocking, multi-threaded, MySQL database and so on.

### Features:

Write pictures described here

User Registration: The system randomly generated account number, the user fill in the appropriate information as requested.
User Login: user login according to their own account and password.
Friends Chat: After a successful login, click on the buddy list of friends to chat.

### registration module

Write pictures described here

The main interface to provide users with new account registration function. In addition to the account number and password entered automatically generated, we also need to verify the identity of the account registration, including real name, gender, phone number.
  After the client acquires information input by the user, the user information is encapsulated as a User object, the request object is encapsulated as CommandTranser, sent to the server. code show as below:

User user = new User(username, password,realname,sex,phone);
CommandTranser msg = new CommandTranser();
msg.setCmd("checkregist");
msg.setData(user);
msg.setReceiver(username);
msg.setSender(username);
//实例化客户端 并且发送数据 这个client客户端 直到进程死亡 否则一直存在
Client client = new Client();
client.sendData(msg);
msg = client.getData();

Client information inputted checksum information input is not allowed to empty, and the corresponding system message, registration request sent by the client to the server, a database server for verification, also returns prompted information.

//注册时,查询是否已经注册该账号
public boolean checkregistUser(User user) {
	PreparedStatement stmt = null;
	Connection conn = null;
	ResultSet rs = null;
	conn = DBHelper.getConnection();
	String sql = "select * from user where username=?";
	try {
		stmt = conn.prepareStatement(sql);
		stmt.setString(1, user.getUsername());
		rs = stmt.executeQuery();
		if (rs.next()) {
			return true;
		}
	}
	return false;
}

Write pictures described here
Write pictures described here

### Login Module

After clicking login, first determine whether the account number and password is blank, then packaged as CommandTranser target, sending data to server, server to verify the account password by comparison with the database.
  Client obtains the transmission request information and the user input code is as follows:

if (e.getSource() == login) {
	String username = text_name.getText().trim();
	String password = new String(text_pwd.getPassword()).trim();
	if ("".equals(username) || username == null) {
		JOptionPane.showMessageDialog(null, "请输入帐号!!");
		return;
	} if ("".equals(password) || password == null) {
		JOptionPane.showMessageDialog(null, "请输入密码!!");
		return;
	}
	User user = new User(username, password);
	CommandTranser msg = new CommandTranser();//封装msg对象发送给服务器
	msg.setCmd("login");msg.setData(user);
	msg.setReceiver(username);msg.setSender(username);
	// 实例化客户端,并且发送数据,这个client客户端直到进程死亡,否则一直存在
	Client client = new Client();
	client.sendData(msg);
	msg = client.getData();
	if (msg != null) {
		if (msg.isFlag()) {
			JOptionPane.showMessageDialog(null, "登陆成功!");
			new FriendsUI(username, client); // 显示好友列表界面
		} else {
			JOptionPane.showMessageDialog(this, msg.getResult());
		}
	}
}

Userservice class server operating database authenticates, if the account number and password is correct, return true, otherwise false. Codes are as follows:

public boolean checkUser(User user) {
	PreparedStatement stmt = null;
	Connection conn = null;
	ResultSet rs = null;
	conn = DBHelper.getConnection();
	String sql = "select * from user where username=? and password =?";
	try {
		stmt = conn.prepareStatement(sql);
		stmt.setString(1, user.getUsername());
		stmt.setString(2, user.getPassword());
		rs = stmt.executeQuery();
		if (rs.next()) {
			return true;
		}
	}
	return false;
}

If the login is successful, it generates a SocketThread objects, comprising a socket, a user account, the SocketThread added to the HashMap<String,Socket>set, and this user receiving thread turn. code show as below:

private CommandTranser execute(CommandTranser msg) {
if ("login".equals(msg.getCmd())) { //登录请求
	UserService userService = new UserService();
	User user = (User) msg.getData();
	msg.setFlag(userService.checkUser(user));
	/*
	 * 如果登陆成功,将该客户端加入已经连接成功的map集合里面 并且开启此用户的接受线程
	 */
	if (msg.isFlag()) {
		// 将该线程加入连接成功的map集合
		SocketThread socketThread = new SocketThread();
		socketThread.setName(msg.getSender());
		socketThread.setSocket(socket);
		SocketList.addSocket(socketThread);
		msg.setResult("登陆成功");
	} else {
		msg.setResult("账号密码输入错误!");
	}
}

HashMap<String,Socket>Used to record all the client has successfully logged on:

public class SocketList {
	private static HashMap<String, Socket> map=new HashMap<String, Socket>();
	//将SocketThread入集合
	public static void addSocket(SocketThread socketThread){
		map.put(socketThread.getName(), socketThread.getSocket());
	}
	public static Socket getSocket(String name){ //通过昵称返回socket
		return map.get(name);
	}
}

Once a chat starts, open a thread for each user, by blocking I / O, client.getData () data sent by a server, if the server processes the data successfully, receive messages, or eject the friends are not online message system.
  Client acquires the message content, sender and receiver, transmits data to the server through CommandTranser, code is as follows:

public void actionPerformed(ActionEvent e) 
	if (e.getSource() == send_btn) {// 如果点击了发送按钮
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a");
		String message = "你说:" + message_txt.getText() + "\t"
				+ sdf.format(date) + "\n";
		chat_txt.append(message);// 在本地文本区追加发送的信息
		CommandTranser msg = new CommandTranser();//msg为客户端向服务器发送的数据
		msg.setCmd("message");
		msg.setSender(owner);
		msg.setReceiver(friend);
		msg.setData(message_txt.getText());
		client.sendData(msg);
		message_txt.setText(null);// 发送信息完毕 写信息的文本框设空
	}
}

Server listening for a message sent by the client, and call CommandTranser execute (CommandTranser msg) method for processing an incoming message, if the process is successful, you can send a message to a friend, if the server fails to process information, send the information to yourself, as follows:

public void run() {
	ObjectInputStream ois = null;
	ObjectOutputStream oos = null;
	while (socket != null) {// 时刻监听 客户端发送来的数据
		try {
			ois = new ObjectInputStream(socket.getInputStream());
			CommandTranser msg = (CommandTranser) ois.readObject();
			msg = execute(msg);
			if ("message".equals(msg.getCmd())) {//服务器处理消息
				if (msg.isFlag()) {
					oos = new ObjectOutputStream(SocketList.getSocket(
							msg.getReceiver()).getOutputStream());
				} else {
					oos = new ObjectOutputStream(socket.getOutputStream());
				}
			}
			oos.writeObject(msg);
		} 
}

Message sent to the server for processing, it is determined whether the online friends, then returned msg:

// 处理客户端发送的信息
private CommandTranser execute(CommandTranser msg) {
	//如果是发送消息的指令,判断当前用户是否在线
	if ("message".equals(msg.getCmd())) {
		// 如果要发送的用户在线 发送信息
		if (SocketList.getSocket(msg.getReceiver()) != null) {
			msg.setFlag(true);
		} else {
			msg.setFlag(false);
			msg.setResult("当前用户不在线");
		}
	}
	return msg;
}

After all the operations done server, the client then receives data returned from the server via the getData (), and displayed in the chat interface, the code is as follows:

public class ClientThread extends Thread {
	private Client client;//客户端对象
	public void run() {
		while (isOnline) {
			//I/O阻塞,接收服务端发送的数据
			CommandTranser msg = client.getData();
			if (msg != null) {
				if (msg.isFlag()) {
					Date date = new Date();
					SimpleDateFormat sdf = new SimpleDateFormat(
							"hh:mm:ss a");
					String message = msg.getSender() + "说:"+ (String) msg.getData() + "\t" + sdf.format(date)+ "\n";
					chat_txt.append(message);
				} else {
					JOptionPane.showMessageDialog(chat_txt, msg.getResult());
				}
			}
		}
	}
}

#### Note: Due to the limited level, do relatively low, all the code and project documentation check my Github, if you like, please give me a Star. (❤ ω ❤)
project all the code and documentation describes

Published 128 original articles · won praise 239 · views 330 000 +

Guess you like

Origin blog.csdn.net/HLK_1135/article/details/63710126