1500 lines of code! Have their own chat room ---- socket chat room implementation (GUI, thread, TCP)

Keywords: Java Database

Java learning punch in: on the 31st and 2nd day [complete the socket chat room construction project]

Java cultivation program (punch in day 31 and day 2)

Content management: implementation of Sockect chat room The Java interface uses various components. Don't worry about what you don't know about this part. It's OK to master one at present

Project demand analysis

The interface and function of a simple chat tool need to be completed to realize the communication between multiple clients under the server transfer. The functions completed by the system are

  • After the program is started, you can see which machines are currently online, and a dialogue and chat box can pop up, in which you can edit the chat information to be sent and send it
  • Once a machine in the network goes online, it can be notified immediately and the user list of the user interface can be updated
  • When you double-click a list item, a dialogue and chat box will pop up, in which you can edit the information to be sent and send it
  • The chat interface is user-friendly. The following is the sending box. There are existing chat records on it, and all chat records of the current time can be seen with the help of the scroll bar
  • When someone sends a message to the machine, it can display the information received by the user, show who sent it, and reply to the information at the same time

Basic analysis

First of all, this is a chat tool. It uses the C/S structure. To simulate, you need to use net's Scott and ServerSocket to simulate the client and server

A variety of knowledge has been comprehensively used here. It is no longer a simple java SE knowledge, in which interface programming occupies the main code. Here you can paste a few pictures to see the effect. It took me two days to finish it, and the connection of polymorphic devices can be realized here

Divided into 3 packages

Sever package is mainly the relevant code of the server, which mainly realizes the interaction with users

Dao package is a simulated database package, which stores all user information and realizes the operation of addition, deletion and modification

Client is the client code package. As long as the code here is run on the computer, the client interface can appear, and the communication can be realized after the ip and port number are agreed. The client software is really realized here, but the software function is simple, and another architecture can be realized by web programming
Let's take a look at the interface

Let's take a look at the communication between the client and the server

Project part code summary

Dao's linked list storage implementation

package Dao;

/**
 * In order to simplify the demonstration program, there is no need to store the database, and the single linked list is used to complete various functions of the database
 * Test code must be written here to check whether various functions are available
 * At the beginning, I tested the add, del and find functions, but did not test the getCount function. There was a problem. Later, I suddenly released the test and found an error
 */
public class UserLinkList {
	private  Node head;
	private int count;

	public boolean addUser(Node client)
	{
		if(head == null)
		{//The head node also stores data
			head = client;
			count++;
			return true;
		}
		else {
			Node p = head;
			for(;p.next != null;p = p.next);
			{
				p.next = client;
				count++;
				return true;
			}
		}
	}
	
	public int getCount() {
		return count;
	}
	
	public Node findUser(String name)
	{
		Node p = head;
		while(p != null )//p. Next! = null does not contain the last node
		{
			if(p.username.equals(name))
			{
				return p;
			}
			p = p.next;
		}
		return null;
	}
	
	public Node findUser(int index)
	{
		int pos = 0;
		Node p = head;
		while(p != null&& pos < index)
		{
			p = p.next;
			pos++;
		}
		if(p != null&& pos == index)
		{
			return p;
		}
		return null;
	}
	
	public boolean delUser(Node client)
	{//After deletion, the length should also be reduced
		Node p = head;
		if(p.username.equals(client.username))
		{//Delete header node
			head = head.next;
			count--;
			return true;
		}
		while(p != null)
		{//Forget the cycle
			if(p.next.username.equals(client.username))
			{
				p.next = p.next.next;
				count--;
				return true;
			}
			p = p.next;
		}
		return false;
	}
	
	/**
	 * Here you can set a display method for inspection
	 */
	public void display() {
		Node p = head;
		int pos = 1;
		while(p != null)
		{
			System.out.println("The first"+pos + "Users"+p.username);
			p = p.next;
			pos++;
		}
	}
}
/*	
	public static void main(String[] args) {//After testing, it is found that there is no problem and can be used normally
		Node client1 = new Node();
		client1.username = "Zhang San ";
		Node client2 = new Node();
		client2.username = "Li Si ";
		Node client3 = new Node();
		client3.username = "Wang Wu ";
		//Other items will not be tested. Anyway, this item can be tested
		UserLinkList userLinkList = new UserLinkList();//Automatic initialization
		userLinkList.addUser(client1);
		userLinkList.addUser(client2);
		userLinkList.addUser(client3);
//		userLinkList.display();
		Node node = userLinkList.findUser(0);
		userLinkList.delUser(node);
		userLinkList.display();
		System.out.println(userLinkList.getCount());
	}
*/

Writing this code now should be very simple, and be careful to test it

ServerListen

Take a brief look at this monitoring thread, which can monitor whether the user is online

package Server;
/**
 * @author OMEY-PC
 *The function of this program is to realize the threading of server listening. The run method uses client = new Node(); creates a client object, sets the interface through client.socket = server.accept, and uses client.input
 *output To create an input / output stream
 */

import java.io.*;
import java.net.*;
import Dao.*; //Connection data
import javax.swing.*;

public class ServerListen extends Thread{
	ServerSocket server;
	JComboBox combobox;
	JTextArea textarea;
	JTextField textfield;
	UserLinkList userLinkList;
	Node client;
	ServerReceive recvThread;
	public boolean isStop;
	/**
	 * User online and offline listening class of chat server
	 */
	public ServerListen(ServerSocket server,JComboBox combobox,JTextArea textarea,JTextField textField,UserLinkList userLinkList) {
		this.server = server;
		this.combobox = combobox;
		this.textarea = textarea;
		this.textfield = textField;
		this.userLinkList = userLinkList;
		isStop = false;
	}
	@Override
	public void run() {
		while(!isStop && !server.isClosed())//The service was not stopped
		{
			try {
				client = new Node();
				client.socket = server.accept();//Used to refer to the connected client
				client.output = new ObjectOutputStream(client.socket.getOutputStream());
				client.output.flush();
				client.input = new ObjectInputStream(client.socket.getInputStream());
				client.username = (String)client.input.readObject();
				//Display prompt information
			    combobox.addItem(client.username);//Change to user name
			    userLinkList.addUser(client);
			    textarea.append("user" + client.username+"go online"+"\n");
			    textfield.setText("Online users"+ userLinkList.getCount()+"people\n");
			    
			    recvThread = new ServerReceive(textarea,textfield,combobox,client,userLinkList);
			    recvThread.start();//Start thread
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

ServerReceive

The thread realizes the information interaction between the server and the user

package Server;
/**
 * @author OMEY-PC
 *Class of server sending and receiving messages
 */

import java.net.ServerSocket;

import javax.swing.*;
import Dao.*;

public class ServerReceive extends Thread{
	JTextArea textarea;//Message display field
	JTextField textfield;//Text input field
	JComboBox combobox; //check box
	Node client;//user
	UserLinkList userLinkList;
	public boolean isStop;
	public ServerReceive(JTextArea textarea, JTextField textfield, JComboBox combobox, Node client,
			UserLinkList userLinkList) {
		this.textarea = textarea;
		this.textfield = textfield;
		this.combobox = combobox;
		this.client = client;
		this.userLinkList = userLinkList;
		isStop = false;
	}
	
	@Override
	public void run()
	{
		//Send a list of users to everyone
		sendUserList();
		while(!isStop && !client.socket.isClosed())
		{
			try {//Type, to whom, status, behavior, information
				String type = (String)client.input.readObject();
				if(type.equalsIgnoreCase("Chat message"))
				{
					String toSomebody =(String)client.input.readObject();//Receive information from client
					String status = (String)client.input.readObject();
					String action = (String)client.input.readObject();
					String message = (String)client.input.readObject();
					String msg = client.username+" "+ action + "yes"+ toSomebody +" say " + message + "\n";//Received messages
					if(status.equalsIgnoreCase("Whisper"))
					{
						msg = "[Whisper]" + msg; //If it's a whisper, put a sign in front of it
					}
					textarea.append(msg);
					if(toSomebody.equalsIgnoreCase("all"))
					{
						sendToAll(msg);//Here is the accepted user message, which is different from the previous message to everyone
					}
					else {//Send messages to users
						try {
							client.output.writeObject("Chat message");
							client.output.flush();//Refresh stream
							client.output.writeObject(msg);
							client.output.flush();
						}catch (Exception e) {
							e.printStackTrace();
						}
						Node node = userLinkList.findUser(toSomebody);
						if(node != null)
						{
							node.output.writeObject("Chat message");
							node.output.flush();
							node.output.writeObject(msg);//Send message to selected message
							node.output.flush();//Flushes the information in the output stream buffer
						}
					}
			    }
				else if(type.equalsIgnoreCase("User offline"))
				{
					Node node = userLinkList.findUser(client.username);
					userLinkList.delUser(node);
					String msg = "user"+ client.username +"Offline\n";
					int count = userLinkList.getCount();
					combobox.removeAllItems();
					combobox.addItem("all");
					int i = 0;
				    while(i < count)
				    {
				    	node = userLinkList.findUser(i);
				    	if(node == null)
				    	{
				    		i++;
				    		continue;
				    	}
				    	combobox.addItem(node.username);
				    	i++;
				    }
					combobox.setSelectedIndex(0);//Choose the first, everyone
					textarea.append(msg);
					textfield.setText("Online users"+ userLinkList.getCount() +"people\n");
					
					sendToAll(msg);
					sendUserList();//Resend user list
					break;
				}
		    }catch (Exception e) {
				e.printStackTrace();
			}
	    }
	}
	/**
	 * Send a message to everyone
	 */
	public void sendToAll(String msg)
	{
		int count = userLinkList.getCount();
		int i = 0;
		while(i < count)
		{//Send a message to everyone in the user list
			Node node = userLinkList.findUser(i);
			if(node == null)
			{
				i++;
				continue;
			}
			try {//Output stream
				node.output.writeObject("Chat message");
				node.output.flush();
				node.output.writeObject(msg);//Chat message write output stream (to client)
				node.output.flush();
			}catch (Exception e) {
				e.printStackTrace();
			}
			i++;
		}
	}
	/**
	 * Send user list to everyone
	 */
	public void sendUserList() {
		String userList = "";
		int count = userLinkList.getCount();
		int i = 0;
		while(i < count)
		{
			Node node = userLinkList.findUser(i);
			if(node == null)
			{
				i++;
				continue;
			}
			userList += node.username;
			userList += "\n";
			i++;
		}
		i = 0; //Send a message to everyone
		while(i < count)
		{
			Node node = userLinkList.findUser(i);
			if(node == null)
			{
				i++;
				continue;
			}
			try {
				node.output.writeObject("User list");
				node.output.flush();
				node.output.writeObject(userList);
				node.output.flush();
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		i++;
	}	
}
/**
 * This program can send messages and user lists to all people through threads, and send chat messages to selected people. It is mainly to realize the threading of sending and receiving messages at the server, in which sendUserList() sends lists,
 * client.input.redObject()Get the message sent by the client to the server, and send the information sent to everyone to each client through sendToAll()
 */

Take another look at the ClientReceive of the client

The thread realizes the information interaction between the client and the system, with rich annotations

package Client;

import java.io.*;
import java.net.*;

import javax.swing.*;

public class ClientReceive extends Thread{
	private JComboBox combobox;
	private JTextArea textarea;
	Socket socket;
	ObjectOutputStream output;
	ObjectInputStream input;
	JTextField showStatus;
	public ClientReceive(JComboBox combobox, JTextArea textarea, Socket socket, ObjectOutputStream output,
			ObjectInputStream input, JTextField showStatus) {
		this.combobox = combobox;
		this.textarea = textarea;
		this.socket = socket;
		this.output = output;
		this.input = input;
		this.showStatus = showStatus;
	}
	
	@Override
	public void run() {//Get message from server
		while(!socket.isClosed())
		{
			try {
				String type = (String)input.readObject();//Get the stream and read the information
				if(type.equalsIgnoreCase("system information "))
				{
					String sysmsg = (String)input.readObject();
					textarea.append("system information " + sysmsg);
				}
				else if(type.equalsIgnoreCase("Service shutdown"))
				{
					output.close();
					input.close();
					socket.close();
					textarea.append("The server has been shut down!\n");
					break;
				}
				else if(type.equalsIgnoreCase("Chat message"))
				{
					String message = (String)input.readObject();
					textarea.append(message);
				}
				else if(type.equalsIgnoreCase("User list"))
				{
					String userlist = (String)input.readObject();
					String[] usernames = userlist.split("\n"); //Separate with newline
					combobox.removeAll();//Move out first
					int i = 0;
					combobox.addItem("all");
					while(i < usernames.length)
					{
						combobox.addItem(usernames[i]);
						i++;
					}
					combobox.setSelectedIndex(0);
					showStatus.setText("Online users"+ usernames.length +" people");
				}
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

The rest of the interface will not be released. The code is too long. There are more than 400 lines each. If you are interested, you can browse my gitee and put the address behind it

Project issues

The user name does not appear in the selection box

Find the corresponding module. It is found that the node added in addItem is not the username in the node. It is normal after modification

The server does not respond when it clicks the send message button

Find the listener part. It is found that the listener listens to the wrong code in this part, and write the button as sysMessage

Online number cannot be displayed

Find the listening thread, start the client, and throw an exception

Cannot invoke "javax.swing.JTextField.setText(String)" because "this.textfield" is null

textfield is empty. Find the source of the problem. It is found in the construction method: the assignmen to variable has no effect. This is because the word is misspelled and the compiler does not report an error

There is no message when the server exits

System error

Cannot read field "input" because "node" is null

Realize that the problem lies in the linked list. The system requires that the serial number in the linked list start from 0, and the serial number in the linked list starts from 1. Fix the pos in findUser in the linked list to 0

After writing this program for two days, it was directly abandoned~~

Posted by van__ on Fri, 15 Oct 2021 11:19:41 -0700