Network Programming TCP Protocol in JAVA Simulates Multiple Clients Accessing the Same Server Case (Multi-Person Chat)

Keywords: Programming socket Java

1. The requirements of the title are as follows:

1. Write client program, connect to the same server, and realize sending thread and receiving thread. The message sent should include "message + sending time" and the message displayed should include "Socket + information + sending time". (GUI implementation follow-up)

2. Write server-side program, use TCP Socket to start port 12345, judge whether the port is occupied or not, and can receive multiple client connections (Welcome + client socket information is successfully sent). Save the Socket in Vector and forward the received information to all connected clients. (GUI implements Follow-up completion)

2. Specific Code Implementation Cases
1. The server-side code is as follows: (first there is a server and then a client, so here is the server-side program first)

package day26.tcp.test;
/*
* Write server-side program, start 12345 port with TCP Socket, judge whether the port is occupied or not, and can receive multiple client connections.
* (The connection successfully sends the welcome message "Welcome"+client socket information, and saves the Socket in Vector to transfer the received information.
* To all connected clients
* */
import java.net.*;
import java.io.*;

public class ServerTest {
    public static void main(String[] args) throws IOException{
    
        System.out.println("The server waits to establish a connection...");     //Server gives prompt information
        
        //Creating Server Socket Objects
        while(true){
            try (ServerSocket ss = new ServerSocket(12345)) {  //Determine whether port 12345 is occupied
               
                Socket s = ss.accept();       //Listening for client Socket objects
                int count = 1;       //Record the number of clients and mark them. The first client is marked 1


                //Start server threads (you can do without multithreading, but to improve efficiency, use multithreading here)
                new Thread(new UserThread(s,count)).start();
                System.out.println("Successful connection!");
        
                count++;        //Next client tag + 1

            }catch (IOException e){
                e.printStackTrace();
            }

        }

    }
}

2. Server-side multithreaded implementation class UserThread

package day26.tcp.test;
/**
 * Server multithreading implementation to improve efficiency
 */

import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class UserThread implements Runnable {      //This class implements the Runnable interface (multithreaded premise)
	//Membership variables are defined as private
    private int count;
    private Socket s;
    
	//Constructing Socket Object and Client Markup count from Receiving Server with Parameters
    public UserThread(Socket s, int count) {
        this.s = s;
        this.count = count;
    }

	//The run() method that must be overridden
    @Override
    public void run() {
        try {
            SimpleDateFormat date = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); //Time to establish a connection
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    s.getOutputStream()));                     //Output stream in Packaging Channel
                    
                    
            //Connection success gives feedback: "Connection time and Welcome+Host+Port"
            String _str = s.getInetAddress().getHostName();
            String str = "Host:" + _str  + "--" + count +   "Number  port:" + s.getPort() ;
            bw.write("Welcome    " + str+ "   " + date.format(new Date()));
            bw.newLine();
            bw.flush();


            //List is used instead of Vector, because List can use Collections tool classes to achieve thread safety and is more efficient than Vector.
            //Add Socket information to the collection
            List<Socket> li = Collections.synchronizedList(
                    new ArrayList<Socket>());
            li.add(s);


            BufferedReader br = new BufferedReader(new InputStreamReader(
                    s.getInputStream()));               //Packaging Input Flow
                  
                    
			//The client receives the information and forwards it to all connected clients
            String line = null;          //Initialize line first
            while ((line = br.readLine()) != null) {
                if(!li.isEmpty()) {         //First, determine whether the set is empty (the premise of enhancing for use)
                    for (Socket _s : li) {          //Enhance for to get all Socket objects in the collection
                        bw.write(str + " Customer said:" + " " + line);     //Forward messages from the current client to all connected clients
                        bw.newLine();
                        bw.flush();

                    }
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. The client code is as follows: (using the sending and receiving threads)

package day26.tcp.test;
/**
*  Write the client program, connect the server, and realize the sending thread and receiving thread. The information sent should include
*  news+Send time, display message should include: Socket+information+Sending time
*  TODO:GUI?(Subsequent completion)
* /

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

public class ClientTest {
    public static void main(String[] args) throws IOException {
    
        //Create Socket objects, specify ip and port
        Socket s = new Socket("192.168.1.174",12345);


        //Packing input and output streams for parameter transfer
        BufferedReader br = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                s.getOutputStream()));
        SeThread st = new SeThread(bw);    //Send Thread Class
        ReThread rt = new ReThread(br);    //Receiving Thread Class


        //Start sending and receiving threads
        new Thread(new SeThread(bw)).start();
        new Thread(new ReThread(br)).start();
        
    }

}

4. Sending thread class SeThread of client

package day26.tcp.test;
/**
 * Client Sender Thread
 */

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SeThread implements Runnable {     //Implementing Runnable Interface

    //Membership variable defines private
    private BufferedWriter bw;       
    
	//Constructions with parameters, input and output stream objects
    public SeThread(BufferedWriter bw) {
        this.bw = bw;
    }


	//Override run() method
    @Override
    public void run() {
        try {
        	//Packing keyboard input
            BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
			
			
			//Client Sends Information
            String line = null;      //Initialize line
            while ((line = buf.readLine()) != null) {
                if ("886".equals(line)) {    //If the client enters 886
                	buf.close();             //Turn off the keyboard input stream
                    bw.close();              //Close the output stream
                    break;
                }

				//Pass the customer's input information to the output stream: "Information + Current Time"
				//Incidental time for client to send information
                SimpleDateFormat date = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");   
                bw.write("""+line + """ + "   " + date.format(new Date()));
                bw.newLine();
                bw.flush();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

5. Client receiving thread class ReThread

package day26.tcp.test;
/**
 * Client receiving thread
 */

import java.io.BufferedReader;
import java.io.IOException;

public class ReThread implements Runnable {    //Implementing Runnable Interface
	//Membership variable defines private
    private BufferedReader br;

    //Constructions with parameters, input stream objects
    public ReThread(BufferedReader br) {
        this.br = br;
    }


	//Override run() method
    @Override
    public void run() {
        try {
            String _line = null;    //Initialization_line
            while ((_line = br.readLine()) != null) {
                System.out.println(_line);    //Print the information received by this client

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

6. Start the server program

7. Start the client program and send messages


8. Because I have only one PC, I can't imitate the situation of multi-client opening at the same time at present, but I can open many client programs on one host at the same time, but because the information in Socket is the same, I can't achieve the expected effect. I hope I can find a solution. If it is solved, I will update this blog.

Posted by mikeoffy69 on Wed, 01 May 2019 15:30:37 -0700