Since I need to create network computer network course design and don’t want to do network wiring or LAN router configuration, etc., I finally decided to use socket to write a LAN chat room based on Java:
For more information about socket and network programming, please refer to my other article: Java socket-based programming
The program is based on the C/S structure, that is, the client server mode.
server:
The default IP is native IP
Both parties need to determine a port number to set the maximum number of people connected. The interface can be started and closed to display the online user and name (this unit is not displayed here)
Client:
Need to manually set the server IP address (LAN)
Manually set the port number and enter the name to connect and disconnect the program running interface as follows:
server:
Client:
I will upload the specific code at the end.
There are many shortcomings in software, such as:
There is no intersection optimization with the database: all users can be stored in the database, and chat records can also be placed in the database. One-to-one chat optimization is not implemented: there are still many shortcomings in the method of redefining one-to-one chat. If you are interested in it, come back and study it slowly.
The following are three codes for the program:
User.java
public class User{ /** * User information class* Used to record user personal information: name and IP */ private String name; private String ip; public User(String name, String ip) { this.name = name; this.ip = ip; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; }}Server_more.java
import java.awt.BorderLayout;import java.awt.Color;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.BindException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.StringTokenizer;import javax.swing.DefaultListModel;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.border.TitledBorder;public class Server_more { private JFrame frame; private JTextArea contentArea; //Text field private JTextField txt_message; //Used to display text information private JTextField txt_max; //Set the maximum number of people connected private JTextField txt_port; //Set port number private JButton btn_start; //Start button private JButton btn_stop; //Disconnect button private JButton btn_send; //Send button private JPanel northPanel; //North panel private JPanel southPanel; //South panel private JScrollPane rightPanel; //Left scroll bar private JScrollPane leftPanel; //Right scroll bar private JSplitPane centerSplit; //Split line private JList userList; //Single component private DefaultListModel listModel; private ServerSocket serverSocket; private ServerThread serverThread; private ArrayList<ClientThread> clients; private boolean isStart = false; // Main method, program execution entry public static void main(String[] args) { new Server_more(); } // Execute message send public void send() { if (!isStart) { JOptionPane.showMessageDialog(frame, "The server has not started yet, and the message cannot be sent! ", "Error", JOptionPane.ERROR_MESSAGE); return; } if (clients.size() == 0) { JOptionPane.showMessageDialog(frame, "No user is online, messages cannot be sent!", "Error", JOptionPane.ERROR_MESSAGE); return; } String message = txt_message.getText().trim(); if (message == null || message.equals("")) { JOptionPane.showMessageDialog(frame, "Message cannot be empty!", "Error", JOptionPane.ERROR_MESSAGE); return; } sendServerMessage(message);// mass server message contentArea.append("Server:" + txt_message.getText() + "/r/n"); txt_message.setText(null); } // Construct the drop method public Server_more() { frame = new JFrame("Server"); // Change the icon of the JFrame: //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png"))); //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png"))); contentArea = new JTextArea(); contentArea.setEditable(false); contentArea.setForeground(Color.blue); txt_message = new JTextField(); txt_max = new JTextField("30"); txt_port = new JTextField("6666"); btn_start = new JButton("Start"); btn_stop = new JButton("Stop"); btn_send = new JButton("Send"); btn_stop.setEnabled(false); listModel = new DefaultListModel(); userList = new JList(listModel); southPanel = new JPanel(new BorderLayout()); southPanel.setBorder(new TitledBorder("Write Message")); southPanel.add(txt_message, "Center"); southPanel.add(btn_send, "East"); leftPanel = new JScrollPane(userList); leftPanel.setBorder(new TitledBorder("online user")); rightPanel = new JScrollPane(contentArea); rightPanel.setBorder(new TitledBorder("Message Display Area")); centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel); centerSplit.setDividerLocation(100); northPanel = new JPanel(); northPanel.setLayout(new GridLayout(1, 6)); northPanel.add(new JLabel("Upper limit")); northPanel.add(txt_max); northPanel.add(new JLabel("Port")); northPanel.add(txt_port); northPanel.add(btn_start); northPanel.add(btn_stop); northPanel.setBorder(new TitledBorder("Configuration Information")); frame.setLayout(new BorderLayout()); frame.add(northPanel, "North"); frame.add(centerSplit, "Center"); frame.add(southPanel, "South"); frame.setSize(600, 400); //frame.setSize(Toolkit.getDefaultToolkit().getScreenSize()); //Set full screen int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width; int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height; frame.setLocation((screen_width - frame.getWidth()) / 2, (screen_height - frame.getHeight()) / 2); frame.setVisible(true); // Event when closing the window frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { if (isStart) { closeServer();// Close the server} System.exit(0);// Exit program} }); // Event txt_message.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { send(); } }); // Event btn_send.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { send(); } }); // Event btn_start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (isStart) { JOptionPane.showMessageDialog(frame, "The server is already in the startup state, do not start repeatedly! ", "Error", JOptionPane.ERROR_MESSAGE); return; } int max; int port; try { try { max = Integer.parseInt(txt_max.getText()); } catch (Exception e1) { throw new Exception("The upper limit of the number of people is a positive integer!"); } if (max <= 0) { throw new Exception("The upper limit of the number of people is a positive integer!"); } try { port = Integer.parseInt(txt_port.getText()); } catch (Exception e1) { throw new Exception("Port number is a positive integer!"); } if (port <= 0) { throw new Exception("Port number is a positive integer!"); } serverStart(max, port); contentArea.append("Server has been started successfully! Upper number of people: " + max + ",port: " + port + "/r/n"); JOptionPane.showMessageDialog(frame, "Server started successfully!"); btn_start.setEnabled(false); txt_max.setEnabled(false); txt_port.setEnabled(false); btn_stop.setEnabled(true); } catch (Exception exc) { JOptionPane.showMessageDialog(frame, exc.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } }); // Event btn_stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!isStart) { JOptionPane.showMessageDialog(frame, "The server has not started yet, no need to stop!", "Error", JOptionPane.ERROR_MESSAGE); return; } try { closeServer(); btn_start.setEnabled(true); txt_max.setEnabled(true); txt_port.setEnabled(true); btn_stop.setEnabled(false); contentArea.append("Server stopped successfully!/r/n"); JOptionPane.showMessageDialog(frame, "Server stopped successfully! "); } catch (Exception exc) { JOptionPane.showMessageDialog(frame, "Exception occurred when the server is stopped!", "Error", JOptionPane.ERROR_MESSAGE); } } }); } // Start the server public void serverStart(int max, int port) throws java.net.BindException { try { clients = new ArrayList<ClientThread>(); serverSocket = new ServerSocket(port); serverThread = new ServerThread(serverSocket, max); serverThread.start(); isStart = true; } catch (BindException e) { isStart = false; throw new BindException("Port number has been occupied, please change it!"); } catch (Exception e1) { e1.printStackTrace(); isStart = false; throw new BindException("Start server exception!"); } } // Close the server @SuppressWarnings("deprecation") public void closeServer() { try { if (serverThread != null) serverThread.stop();// Stop the server thread for (int i = clients.size() - 1; i >= 0; i--) { // Send the close command to all online users clients.get(i).getWriter().println("CLOSE"); clients.get(i).getWriter().flush(); // Release the resource clients.get(i).stop();// Stop this thread serving the client clients.get(i).reader.close(); clients.get(i).writer.close(); clients.get(i).socket.close(); clients.remove(i); } if (serverSocket != null) { serverSocket.close();// Close the server-side connection} listModel.removeAllElements();// Clear the user list isStart = false; } catch (IOException e) { e.printStackTrace(); isStart = true; } } // Bulk server message public void sendServerMessage(String message) { for (int i = clients.size() - 1; i >= 0; i--) { clients.get(i).getWriter().println("Server:" + message + "(Multiple send)"); clients.get(i).getWriter().flush(); } } // Server thread class ServerThread extends Thread { private ServerSocket serverSocket; private int max;// Upper number of people// Constructing method of server thread public ServerThread(ServerSocket serverSocket, int max) { this.serverSocket = serverSocket; this.max = max; } public void run() { while (true) {// Keep waiting for the client link try { Socket socket = serverSocket.accept(); if (clients.size() == max) {// If the maximum number of people has been reached BufferedReader r = new BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter w = new PrintWriter(socket .getOutputStream()); // Receive basic user information from the client String inf = r.readLine(); StringTokenizer st = new StringTokenizer(inf, "@"); User user = new User(st.nextToken(), st.nextToken()); // Feedback connection success information w.println("MAX@Server: Sorry," + user.getName() + user.getIp() + ", the number of people online on the server has reached the upper limit, please try connecting later! "); w.flush(); // Release the resource r.close(); w.close(); socket.close(); continue; } ClientThread client = new ClientThread(socket); client.start();// Start the threads for this client service clients.add(client); listModel.addElement(client.getUser().getName());// Update the online list contentArea.append(client.getUser().getName() + client.getUser().getIp() + "Online!/r/n"); } catch (IOException e) { e.printStackTrace(); } } } } } // Thread serving a client class ClientThread extends Thread { private Socket socket; private BufferedReader reader; private PrintWriter writer; private User user; public BufferedReader getReader() { return reader; } public PrintWriter getWriter() { return writer; } public User getUser() { return user; } // Constructor of client thread public ClientThread(Socket socket) { try { this.socket = socket; reader = new BufferedReader(new InputStreamReader(socket .getInputStream())); writer = new PrintWriter(socket.getOutputStream()); // Receive basic user information from the client String inf = reader.readLine(); StringTokenizer st = new StringTokenizer(inf, "@"); user = new User(st.nextToken(), st.nextToken()); // Feedback connection success information writer.println(user.getName() + user.getIp() + "Connect to the server successfully!"); writer.flush(); // Feedback to the current online user information if (clients.size() > 0) { String temp = ""; for (int i = clients.size() - 1; i >= 0; i--) { temp += (clients.get(i).getUser().getName() + "/" + clients .get(i).getUser().getIp()) + "@"; } writer.println("USERLIST@" + clients.size() + "@" + temp); writer.flush(); } // Send the user online command to all online users for (int i = clients.size() - 1; i >= 0; i--) { clients.get(i).getWriter().println( "ADD@" + user.getName() + user.getIp()); clients.get(i).getWriter().flush(); } } catch (IOException e) { e.printStackTrace(); } } @SuppressWarnings("deprecation") public void run() {// Continuously receive messages from the client for processing. String message = null; while (true) { try { message = reader.readLine();// Receive client messages if (message.equals("CLOSE"))// Offline command { contentArea.append(this.getUser().getName() + this.getUser().getIp() + "Offline!/r/n"); // Disconnect and release resources reader.close(); writer.close(); socket.close(); // Send the user's offline command to all online users for (int i = clients.size() - 1; i >= 0; i--) { clients.get(i).getWriter().println( "DELETE@" + user.getName()); clients.get(i).getWriter().flush(); } listModel.removeElement(user.getName());// Update the online list// Delete this client service thread for (int i = clients.size() - 1; i >= 0; i--) { if (clients.get(i).getUser() == user) { ClientThread temp = clients.get(i); clients.remove(i);// Delete this user's service thread temp.stop();// Stop this service thread return; } } } else { dispatcherMessage(message);// Forward message} } catch (IOException e) { e.printStackTrace(); } } } // Forward message public void dispatcherMessage(String message) { StringTokenizer stringTokenizer = new StringTokenizer(message, "@"); String source = stringTokenizer.nextToken(); String owner = stringTokenizer.nextToken(); String content = stringTokenizer.nextToken(); message = source + ":" + content; contentArea.append(message + "/r/n"); if (owner.equals("ALL")) {// Bulk for (int i = clients.size() - 1; i >= 0; i--) { clients.get(i).getWriter().println(message + "(multiple send)"); clients.get(i).getWriter().flush(); } } } } } } }Client_more.java
import java.awt.BorderLayout;import java.awt.Color;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.HashMap;import java.util.Map;import java.util.StringTokenizer;import javax.swing.DefaultListModel;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.border.TitledBorder;public class Client_more{ private JFrame frame; private JList userList; private JTextArea textArea; private JTextField textField; private JTextField txt_port; private JTextField txt_hostIp; private JTextField txt_name; private JButton btn_start; private JButton btn_stop; private JButton btn_send; private JPanel northPanel; private JPanel southPanel; private JScrollPane rightScroll; private JScrollPane leftScroll; private JSplitPane centerSplit; private DefaultListModel listModel; private boolean isConnected = false; private Socket socket; private PrintWriter writer; private BufferedReader reader; private MessageThread messageThread;// The thread responsible for receiving messages private Map<String, User> onLineUsers = new HashMap<String, User>();// All online users// Main method, program entry public static void main(String[] args) { new Client_more(); } // Execute sending public void send() { if (!isConnected) { JOptionPane.showMessageDialog(frame, "The server has not been connected to it yet, and the message cannot be sent! ", "Error", JOptionPane.ERROR_MESSAGE); return; } String message = textField.getText().trim(); if (message == null || message.equals("")) { JOptionPane.showMessageDialog(frame, "Message cannot be empty!", "Error", JOptionPane.ERROR_MESSAGE); return; } sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message); textField.setText(null); } // Constructor public Client_more() { textArea = new JTextArea(); textArea.setEditable(false); textArea.setForeground(Color.blue); textField = new JTextField(); txt_port = new JTextField("6666"); txt_hostIp = new JTextField("127.0.0.1"); txt_name = new JTextField("Wu Chengqian"); btn_start = new JButton("Connection"); btn_stop = new JButton("Disconnect"); btn_send = new JButton("Send"); listModel = new DefaultListModel(); userList = new JList(listModel); northPanel = new JPanel(); northPanel.setLayout(new GridLayout(1, 7)); northPanel.add(new JLabel("Port")); northPanel.add(txt_port); northPanel.add(new JLabel("Server IP")); northPanel.add(txt_hostIp); northPanel.add(new JLabel("name")); northPanel.add(txt_name); northPanel.add(btn_start); northPanel.add(btn_stop); northPanel.setBorder(new TitledBorder("Connection Information")); rightScroll = new JScrollPane(textArea); rightScroll.setBorder(new TitledBorder("Message Display Area")); leftScroll = new JScrollPane(userList); leftScroll.setBorder(new TitledBorder("Online User")); southPanel = new JPanel(new BorderLayout()); southPanel.add(textField, "Center"); southPanel.add(btn_send, "East"); southPanel.setBorder(new TitledBorder("write message")); centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll, rightScroll); centerSplit.setDividerLocation(100); frame = new JFrame("Client"); // Change the icon of the JFrame: // frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png"))); frame.setLayout(new BorderLayout()); frame.add(northPanel, "North"); frame.add(centerSplit, "Center"); frame.add(southPanel, "South"); frame.setSize(600, 400); int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width; int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height; frame.setLocation((screen_width - frame.getWidth()) / 2, (screen_height - frame.getHeight()) / 2); frame.setVisible(true); // Event when pressing Enter in the text box for writing the message textField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { send(); } }); // Event btn_send.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { send(); } }); // Event btn_start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int port; if (isConnected) { JOptionPane.showMessageDialog(frame, "It is already on the connection, do not repeat the connection!", "Error", JOptionPane.ERROR_MESSAGE); return; } try { try { port = Integer.parseInt(txt_port.getText().trim()); } catch (NumberFormatException e2) { throw new Exception("Port number does not meet the requirements! The port is an integer!"); } String hostIp = txt_hostIp.getText().trim(); String name = txt_name.getText().trim(); if (name.equals("") || hostIp.equals("")) { throw new Exception("Name and server IP cannot be empty!"); } boolean flag = connectServer(port, hostIp, name); if (flag == false) { throw new Exception("Connect to the server failed!"); } frame.setTitle(name); JOptionPane.showMessageDialog(frame, "Connected successfully!"); } catch (Exception exc) { JOptionPane.showMessageDialog(frame, exc.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } }); // Event btn_stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (!isConnected) { JOptionPane.showMessageDialog(frame, "It is already in a disconnected state, do not disconnect repeatedly!", "Error", JOptionPane.ERROR_MESSAGE); return; } try { boolean flag = closeConnection();// Disconnect if (flag == false) { throw new Exception("Exception occurred when disconnecting! "); } JOptionPane.showMessageDialog(frame, "Successfully disconnected!"); } catch (Exception exc) { JOptionPane.showMessageDialog(frame, exc.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } }); // Event when closing the window frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { if (isConnected) { closeConnection();// Close the connection} System.exit(0);// Exit the program} }); } /** * Connect to the server* * @param port * @param hostIp * @param name */ public boolean connectServer(int port, String hostIp, String name) { // Connect to the server try { socket = new Socket(hostIp, port);// Establish a connection based on the port number and server ip writer = new PrintWriter(socket.getOutputStream()); reader = new BufferedReader(new InputStreamReader(socket .getInputStream())); // Send basic information of the client user (user name and ip address) sendMessage(name + "@" + socket.getLocalAddress().toString()); // Open the thread to receive messages messageThread = new MessageThread(reader, textArea); messageThread.start(); isConnected = true;// has been connected to return true; } catch (Exception e) { textArea.append("The server with port number: " + port + " IP address: " + hostIp + " failed!" + "/r/n"); isConnected = false;// return false on not connected; } } /** * Send message* * @param message */ public void sendMessage(String message) { writer.println(message); writer.flush(); } /** * Client actively closes the connection*/ @SuppressWarnings("deprecation") public synchronized boolean closeConnection() { try { sendMessage("CLOSE");// Send disconnect command to the server messageThread.stop();// Stop accepting message thread// Release resource if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } if (socket != null) { socket.close(); } isConnected = false; return true; } catch (IOException e1) { e1.printStackTrace(); isConnected = true; return false; } } // Thread that constantly receives messages class MessageThread extends Thread { private BufferedReader reader; private JTextArea textArea; // Constructing method for receiving message thread public MessageThread(BufferedReader reader, JTextArea textArea) { this.reader = reader; this.textArea = textArea; } // Passively close the connection public synchronized void closeCon() throws Exception { // Clear the user listModel.removeAllElements(); // Passively close the connection and release the resource if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } if (socket != null) { socket.close(); } isConnected = false;// Modify the status to disconnect} public void run() { String message = ""; while (true) { try { message = reader.readLine(); StringTokenizer stringTokenizer = new StringTokenizer( message, "/@"); String command = stringTokenizer.nextToken();// Command if (command.equals("CLOSE"))// Server closed command { textArea.append("Server closed!/r/n"); closeCon();// Passively close the connection return;// End thread} else if (command.equals("ADD")) {// Some users are updating the online list String username = ""; String userIp = ""; if ((username = stringTokenizer.nextToken()) != null && (userIp = stringTokenizer.nextToken()) != null) { User user = new User(username, userIp); onLineUsers.put(username, user); listModel.addElement(username); } } else if (command.equals("DELETE")) {// Some users are downdating the online list String username = stringTokenizer.nextToken(); User user = (User) onLineUsers.get(username); onLineUsers.remove(user); listModel.removeElement(username); } else if (command.equals("USERLIST")) {// Load online user list int size = Integer .parseInt(stringTokenizer.nextToken()); String username = null; String userIp = null; for (int i = 0; i < size; i++) { username = stringTokenizer.nextToken(); userIp = stringTokenizer.nextToken(); User user = new User(username, userIp); onLineUsers.put(username, user); listModel.addElement(username); } } else if (command.equals("MAX")) {// The number of people has reached the upper limit textArea.append(stringTokenizer.nextToken() + stringTokenizer.nextToken() + "/r/n"); closeCon();// Passively close the connection JOptionPane.showMessageDialog(frame, "The server buffer is full! ", "Error", JOptionPane.ERROR_MESSAGE); return;// End thread} else {// Normal message textArea.append(message + "/r/n"); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } } }The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.