directory

Overall development idea

The server side

Server interface Design

Establish TCP server communication

Establish the server message sending output stream

Establish the server message receive input stream

Set up the server real-time message communication thread

Set the server communication to be disconnected freely

The client

Client interface design

Establish TCP client communication

Establish a client message sending output stream

Establish the client message receiving input stream

Establish the client real-time communication thread

Example Set the client communication to be disconnected freely

Gets the current time function

Text box contents display different effects

Checks whether a string is an IP address


Helllo! Hello, I’m grey Ape! A super Bug writing program ape!

Recently, when I was studying network communication, I had an idea to imitate wechat to make a simple network chat room, so TODAY I am here to record the development process.

First look at a wave of renderings:

Including message input box and message receiving box, two users (client and server) can communicate with each other in real time.

 

Overall development idea

The development of network chat room is based on TCP/IP protocol and established, through the specified IP address and port number for real-time communication, on the use of TCP/IP protocol communication foundation learning, you can see my blog “Java using TCP protocol to achieve client and server communication”. This is the Java language to establish TCP protocol and socket use to do more detailed explanation.

First record the overall idea of the chat room project development:

  1. Design and complete the interface between client and server
  2. Create internal listener classes or listener functions for each button
  3. The client and server establish communication based on TCP/IP
  4. Write client and server communication threads respectively to monitor the sending and receiving of messages from both sides
  5. Write communication disconnection function to realize network communication disconnection

Well, the above five steps are the main development process, there are many need to write and pay attention to the small details, next to share the network chat room project detailed development ideas, at the same time attach the corresponding source:

 

The server side

Server interface Design

The interface design of the server side mainly includes the following elements: connect, disconnect, send button, message input box, message receive box, port number input box, etc. According to the interface principle of wechat on PC side, we can simply design according to our own ideas. The interface of the server side I designed is as follows:

Then, according to the design, the following tasks should be completed:

 

Establish TCP server communication

According to the TCP communication principle, a communication protocol needs to be established on the server based on the port number, and then a client socket is established on the client in the same way to realize the communication connection.

On the server side, according to the actual need, the network communication should be after the user input the communication port number and click the connection button, then the server side communication, so this section of code should be written in the connection button listener function, here is to establish the connection button internal listener class:

// Set the connection button internal listener class
class ConnectJBClass implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		// Check whether the port input box is empty
		if (portText.getText().equals("")) {
			JOptionPane.showMessageDialog(null."Please enter the port number of the connection!"."Tip", JOptionPane.ERROR_MESSAGE);
		}
		else {	
			// If the input port is not an integer, an exception is thrown
			try {
				port = Integer.parseInt(portText.getText());	// Get the port number entered by the user
				isCorrectPort = true;	// If the user enters the correct port number, set it to true
			} catch (Exception e2) {
				// TODO: handle exception
				JOptionPane.showMessageDialog(null."Please enter the correct port number!"."Tip", JOptionPane.ERROR_MESSAGE);
			}
			
			// Continue if a correctly formatted port number is entered, otherwise no execution is performed
			if (isCorrectPort) {
					
				try {
					server = new ServerSocket(port);	// To create a server, enter port for the user
					stateJL.setText("Waiting for connection...");
					System.out.println("The port number is" + Integer.toString(port) + "" ");
					client = server.accept();	// Call the server function to connect to the client
					stateJL.setText("IP:" + client.getInetAddress());
					isConnect = true;	// Establish communication
					threadConnect.start();// Start the communication thread after the connection is successful
				} catch (IOException e1) {
					JOptionPane.showMessageDialog(null."Client disconnected!"."Tip", JOptionPane.ERROR_MESSAGE);							
				}
					
			}			
		}
	}
		
}
Copy the code

 

Establish the server message sending output stream

After the communication is established, it is to realize the information interaction between the two sides. First of all, we should complete one-way communication from the client to the server or from the server to the client, and then carry out two-way communication. Here we first complete sending from the server to the client, and the client communicates with the server using the same method. This code is also done in the internal listener class for the send button:

// Set the send button internal listener class
class ShendJBClass implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		try {			
			String putText = sendWindow.getText();	// Get the text entered by the server user
			String putTime = getTime();
			setInfoWindosFont(putTime, Color.blue, false.15);
			setInfoWindosFont(putText, Color.black, false.20);
			sendWindow.setText("");		// Clear the sending box after sending
			OutputStream put = client.getOutputStream();	// Define the output stream to be sent to the client
			put.write(putText.getBytes());	// Send the text to bytes
		} catch (IOException e1) {
			// TODO Auto-generated catch block}}}Copy the code

 

Establish the server message receive input stream

This step to complete is to receive the message sent by the client, here according to the TCP/IP protocol, to establish the message input flow object, so as to achieve the message receiving: the client receives in the same way, the specific code is as follows:

try {
	InputStream iStream = client.getInputStream();	// Get the input stream from the client
	byte [] b = new byte[1024];
	int len = iStream.read(b);	// Read data in binary form
	String data = new String(b,0,len);	// The received content
	String infoTime = getTime();	// The time the message was sent
	setInfoWindosFont(infoTime, Color.red, false.15);
	setInfoWindosFont(data, Color.black, false.20);
							
	/* Puts the scroll bar at the bottom of the text box */												infoWindow.setSelectionStart(infoWindow.getText().length());
        JScrollBar jSBInfo = jScrollPaneInfo.getVerticalScrollBar();
        jSBInfo.setValue(jSBInfo.getMaximum());
} catch (IOException e) {
        // TODO Auto-generated catch block
	e.printStackTrace();
}
Copy the code

 

Set up the server real-time message communication thread

More than we can finish the basic of the client and server two-way communication, that is to say, our client can receive the message from the server, the server can also receive the news from the client, but it is important to note that the above we build the communication is a single, that is to say, can only be implemented once send and receive, so obviously it is not possible, The actual development of the chat room should be able to communicate under the premise of unimpeded communication has been right, so we are going to solve such a problem.

Realize the client and the server method of real-time communication is actually very simple, we only need to the client or server sends the message of real-time monitoring, as long as there is news once listen to send, so we will receive the message in the corresponding message box is displayed, so here want to use the method of thread, specific code is as follows:

// Communication thread
threadConnect = new Thread(new Runnable() {
			
    @Override
    public void run(a) {
	// TODO Auto-generated method stub
	while (true) {
	    // If the connection is already established
	    if (isConnect) {
		try {
		InputStream iStream = client.getInputStream();	// Get the input stream from the client
		byte [] b = new byte[1024];
		int len = iStream.read(b);	// Read data in binary form
		String data = new String(b,0,len);	// The received content
		String infoTime = getTime();	// The time the message was sent
		setInfoWindosFont(infoTime, Color.red, false.15);
		setInfoWindosFont(data, Color.black, false.20);
							
		/* Puts the scroll bar at the bottom of the text box */																							        infoWindow.setSelectionStart(infoWindow.getText().length());
		JScrollBar jSBInfo =  jScrollPaneInfo.getVerticalScrollBar();
		jSBInfo.setValue(jSBInfo.getMaximum());
		} catch (IOException e) {
		// TODO Auto-generated catch blocke.printStackTrace(); }}else {
	    stateJL.setText("Server not connected!");
	    break; }}}});Copy the code

 

Set the server communication to be disconnected freely

After the completion of the above, our chat room can achieve two-way real-time communication, but this is only communication, just like when we use wechat, and the other party offline situation appears right, so here we are also established a client and server disconnect Settings. After clicking the disconnect button, the client and server cannot communicate with each other. In fact, it is very simple to close the socket between the client and server. The specific code is as follows:

// Set the disconnect button internal listener class
class CloseConnectJBClass implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		isConnect = false;	// The server is disconnected
		try {
			server.close();	// Stop the server
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			JOptionPane.showMessageDialog(null."The server is disconnected!"."Tip", JOptionPane.ERROR_MESSAGE);					
		}
		/ / JOptionPane. ShowMessageDialog (null, "server has been disconnected!" , "hint ", joptionpane.error_message);}}Copy the code

 

The client

On the client side we also need to write in the same way as on the server side,

Client interface design

First is the interface design, the effect is as follows:

 

Establish TCP client communication

Slightly different from the server, the communication on the client is based on the IP address and port number. That is to say, when establishing the communication on the client, we need to enter the IP address of the communication and the same port number on the server, so as to establish the communication between the two sides. Set up client communication is implemented in the client connection button, here set up the client connection button internal listener class:

// Add an internal event listener class for the connection button
class ConnectJBClass implements ActionListener{
		
	@Override
	public void actionPerformed(ActionEvent e) {
			
		// Check whether the port input box and IP input box are empty
		if (portText.getText().equals("Port number")||ipTextArea.getText().equals("IP address")) {
			JOptionPane.showMessageDialog(null."Please enter the full IP and port number!"."Tip", JOptionPane.ERROR_MESSAGE);
		}
		else {
			// Determine the format of user input
			try {
				ipClient = ipTextArea.getText();	// The IP address entered by the user is obtained
				// If the IP address is correct
				if (isCorrectIp2(ipClient)) {
					isCorrectIp = true;
				}
				else {
					JOptionPane.showMessageDialog(null."Please enter the correct format of IP!"."Tip", JOptionPane.ERROR_MESSAGE);
				}
				port = Integer.parseInt( portText.getText());	// Get the port number entered by the user
				isCorrectPort = true;
				// system.out. println(" Correct port! ") );
			} catch (Exception e2) {
				// TODO: handle exception
				JOptionPane.showMessageDialog(null."Please enter a correctly formatted port number!"."Tip", JOptionPane.ERROR_MESSAGE);
			}
			// If the user entered the correct IP address and port format
			if (isCorrectIp&&isCorrectPort) {
				JOptionPane.showMessageDialog(null."Entered complete, connecting...... \nIP:" + ipClient, "Tip", JOptionPane.ERROR_MESSAGE);
				/******* After the judgment is correct, the judgment variable is assigned an initial value so that the next input can determine ********/
				isCorrectIp = false;
				isCorrectPort = false;
				 try {
					client = new Socket(ipClient,port);		// Create a client
					stateJL.setText("Client connection successful!");
					isConnect = true;	// The connection has been established
					threadConnect.start();// Start the communication thread
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					JOptionPane.showMessageDialog(null."Client connection failed!"."Tip", JOptionPane.ERROR_MESSAGE);
						
				}
			}
		}
	}
		
}
Copy the code

 

Establish a client message sending output stream

// Set the send button internal listener class
class ShendJBClass implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		try {				
			String putText = sendWindow.getText();	// Get the text entered by the client user
			String putTime = getTime();
			setInfoWindosFont(putTime, Color.blue, false.15);
			setInfoWindosFont(putText, Color.black, false.20);
			sendWindow.setText("");		// Clear the sending box after sending
			OutputStream put = client.getOutputStream();	// Define the output stream sent to the server
			put.write(putText.getBytes());	// Send the text to bytes
		} catch (IOException e1) {
			
		}		
	}	
}
Copy the code

 

Establish the client message receiving input stream

try {
	InputStream input = client.getInputStream();
	byte [] infoByte = new byte[1024];
	int len = input.read(infoByte);
	String infoTime = getTime();	// Get the current time
	String data = new String(infoByte,0,len);	// Get the received message
	String oldText = infoWindow.getText();	// Get the contents of the previous text box
	String atText = oldText + "\n" + infoTime + "\n" + data;	// What will be displayed in the text box
	System.out.println(atText);
	setInfoWindosFont(infoTime, Color.RED, false.15);
	setInfoWindosFont(data, Color.black, false.20);
	//infoWindow.setText(atText);
							
	/* Puts the scroll bar at the bottom of the text box */	
	infoWindow.setSelectionStart(infoWindow.getText().length());	
        JScrollBar jSBInfo = jScrollPaneInfo.getVerticalScrollBar();
	jSBInfo.setValue(jSBInfo.getMaximum());
							
	} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}
Copy the code

 

Establish the client real-time communication thread

// Communication thread
threadConnect = new Thread(new Runnable() {
	@Override
	public void run(a) {
	// TODO Auto-generated method stub
	while (true) {		
		if (isConnect) {	
			stateJL.setText("Correspondence!");
			try {
			InputStream input = client.getInputStream();
			byte [] infoByte = new byte[1024];
			int len = input.read(infoByte);
			String infoTime = getTime();	// Get the current time
			String data = new String(infoByte,0,len);	// Get the received message
			String oldText = infoWindow.getText();	// Get the contents of the previous text box
			String atText = oldText + "\n" + infoTime + "\n" + data;	// What will be displayed in the text box
			System.out.println(atText);
							setInfoWindosFont(infoTime, Color.RED, false.15);
			setInfoWindosFont(data, Color.black, false.20);
			//infoWindow.setText(atText);
							
			/* Puts the scroll bar at the bottom of the text box */	
			infoWindow.setSelectionStart(infoWindow.getText().length());
			JScrollBar jSBInfo = jScrollPaneInfo.getVerticalScrollBar();
			jSBInfo.setValue(jSBInfo.getMaximum());
							
			} catch (IOException e) {
			// TODO Auto-generated catch blocke.printStackTrace(); }}else {
			    stateJL.setText("Client is disconnected......");
			    break; }}}});Copy the code

 

Example Set the client communication to be disconnected freely

// Set the disconnect button internal listener class
class CloseConnectJBClass implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
	isConnect = false;	// The server is disconnected
	/ / JOptionPane. ShowMessageDialog (null, "client side has broken out!" , "hint ", joptionpane.error_message);
	try {
		client.close();	// Abort the client
	} catch (IOException e1) {
		JOptionPane.showMessageDialog(null."Client is disconnected!"."Tip", JOptionPane.ERROR_MESSAGE); }}}Copy the code

 

After both the client and the server are completed, so that our server and client can connect and disconnect two-way real-time communication,

However, there are many small details that need to be paid attention to during actual development, and the Big Bad Wolf is listed here.

 

Gets the current time function

In order to observe in real time when we send and receive messages, we need to have a function that gets the current time. The code is as follows:

// Define a method to get the current time
public String getTime(a)
{
	Date date = new Date();
		
	SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
	SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
	SimpleDateFormat dayFormat = new SimpleDateFormat("dd");
	SimpleDateFormat hourFormat = new SimpleDateFormat("HH");
	SimpleDateFormat minuteFormat = new SimpleDateFormat("mm");
	SimpleDateFormat secondFormat = new SimpleDateFormat("ss");
		
	String year = yearFormat.format(date);
	String month = monthFormat.format(date);
	String day = dayFormat.format(date);
	String hour = hourFormat.format(date);
	String minute = minuteFormat.format(date);
	String second = secondFormat.format(date);
		
	return year + ":" + month + ":" + day + ":" + hour + ":" + minute + ":" + second;
	}
	
Copy the code

 

Text box contents display different effects

From the above effect display, we can see that the time displayed in the text box and the font color and properties displayed in the message sent by the client server are different.

We know that in practical application, the Chinese text box is in the form of pure text, which cannot achieve the above effect. Therefore, for the message receiving box, we use the JTextPane text field and set the font style we want to display in it. For a detailed tutorial on how to display text, see my article “Java Text box displays different color, size, and other properties”. The function code is as follows:

// Set the receiver box text font properties
public void setInfoWindosFont(String str, Color col,boolean bold,int fontSize) {
	SimpleAttributeSet attrSet = new SimpleAttributeSet();
	StyleConstants.setForeground(attrSet, col);// Set the color
	if (bold) {
		StyleConstants.setBold(attrSet, bold);// Set bold
	}
	StyleConstants.setFontSize(attrSet, fontSize);// Set the size
	
	/ * * * * * * * * * infoWindow for JTextPane text domain name * * * * * * * * * * * * * * * * * /
	Document doc = infoWindow.getDocument();	
	str = "\n" + str;
	try {
		doc.insertString(doc.getLength(), str, attrSet);
	} catch (BadLocationException e) {
		// TODO Auto-generated catch block
		//e.printStackTrace();
		JOptionPane.showMessageDialog(null."Wrong font Settings!"."Tip", JOptionPane.ERROR_MESSAGE); }}Copy the code

 

Checks whether a string is an IP address

When we write the client, we need to input the IP address of network communication, so we need to judge whether the IP address entered by the user is correct, in case the program goes wrong, so here we need to judge the input string (IP address). A detailed explanation of whether a string is an IP address can be found in the blog “Algorithm – Determining whether a string is an IP address”. Here I list a method used in the program to determine whether a string is an IP address. The method is based on regular expressions and the code is as follows:

// Use regular expressions to determine whether a character is an IP
public boolean isCorrectIp2(String ipString) {
	String ipRegex = "\ \ d {1, 3} \ \ \ \ d {1, 3} \ \ \ \ d {1, 3} \ \ \ \ d {1, 3}";	// Regular expression for the IP address
	// If the first three values are satisfied, check whether each segment is between 0 and 255
	if (ipString.matches(ipRegex)) {
		String[] ipArray = ipString.split("\ \.");
		for (int i = 0; i < ipArray.length; i++) {
			int number = Integer.parseInt(ipArray[i]);
			//4. Check whether each digit is between 0 and 255
			if (number <0||number>255) {
				return false; }}return true;
	}
	else {
		return false;	// If the regular expression does not match, false is returned}}Copy the code

Ok, so much for the development of the Internet chat room,

The full source code is available at the following link:

** Click to obtain the full source code ****** extract code: 2heo

Feel good remember to like attention yo!

Big bad Wolf accompany you to progress together!