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.