⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.java

📁 Simple Chat Application using Java Socket Programming.
💻 JAVA
字号:
import javax.swing.*;
import javax.swing.BoxLayout;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.io.*;
import java.net.*;


///////////////////////////////SERVER CLASS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

public class Server extends JFrame implements Runnable		
{
	private static int size = 10; 	//Number of clients which server can handle
	private static PrintStream [] users = new PrintStream[size];	//user array to handle conversations over the server
	private static Message message = new Message();		//Message object to send user messages to other clients
	private static Label lbl = new Label("           <<<<<<<<<<<<<<<<<<<<<<<SERVER>>>>>>>>>>>>>>>>>>>>>");
	private static Label[] label = new Label[size];		//Label array to print out which client the server is pinging 
	private static TextArea txtout;		//when server is connected it shows a message
	
	private static ServerSocket s;	//Server socket to create a connection
	private static int port = 9001;	 //default port for connection
	
	public Server()			//Server constructor
	{
		super("Server");	//initializing the window
		txtout = new TextArea(2,5);		//setting textarea properties
		txtout.setFont(new Font("Courier", Font.PLAIN, 12));	//Setting font size
		txtout.setEditable(false);	//textarea shouldn't be edited by the user

		JPanel panel = new JPanel();	//creating the panel for arranging objects
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));	//Setting layout to BoxLayout

		panel.add(lbl);
		panel.add(txtout);					//Adding objects to the panel
		for(int i=0; i<size; i++)
		{
			label[i] = new Label(i+". Client hasn't signed in...");		//adding label array to the panel
			panel.add(label[i]);
		}
		Container contentPane = getContentPane();
		contentPane.add(panel, BorderLayout.CENTER);	//adding pannel to the center of the window
		
		setSize( 450, 380 ); 		// set size of the window
		setVisible(true);			//set visibility to true to be able to see the frame
	}
	
	public void run() 			//run method
	{
		try 
		{	
			s = new ServerSocket(port);			//creating connection on the pre-defined port
			System.out.println("Server started");	//when server is connected print a message
			txtout.append("Server started\n");
			for(int i= 0; i < size; i++)
			{	
				users[i] = null;			//initially setting all PrintStream objects to null 
			}		
			new Sender().start();		//running sender class (Thread) to send messages to the active users
			while(true)					//always perform these actions
			{	
				try 
				{
					Thread.sleep(500);	//sleep 500ms for other threads can run
				} 
				catch (InterruptedException e) 
				{
					e.printStackTrace();
				}
				System.out.println("Waiting for Clients...");	//After server creates a connection it waits clients to connect
				txtout.append("Waiting for Clients...\n");		//so it prints a message
				Socket soc = s.accept( );		//when a user tries to connect to the server a socket will be accepted by the server to ensure the connection
				System.out.println("A Client connected");	//after socket connection a message wil be printed
				txtout.append("A Client connected\n");
				boolean found = false;	//Since there is no user found is initially false until server realizes a user request
				int user_count = 0;	//initially there is no active user
				
				for(int i = 0; i < size; i++)	//we will check all users if they are connected
				{
					if(users[i] == null)	//if there is not a user on that socket
					{	
						if(!found)			//if no user is found (socket is not occupied)
						{
							users[i] = new PrintStream(soc.getOutputStream());	//creating connection for the user
							new Connection(soc, i).start();		//starting connection thread for the user
							found = true;	//socket is occupied now
						}
					}
					else user_count++;	// if socket is already occupied user_count will be increased by 1
				}
			}
		}
		catch (Exception e) 	//if any exception occurs print the exception message
		{	
			System.err.println("Error: " + e);
		} 
	} 
	
	public void destroy()	//closes the window
	{	
		try
		{
			s.close();	//closing Server socket so connection will be interrupted
		}
		catch(Exception e)	//print exception message if any exception occurs
		{
			System.out.println("Error: "+e);
		}
	}
	
	public static void main(String args[])
	{
		Server s = new Server();	//starting the Server
		s.run();
	}
 
	private static class Connection extends Thread  // Several Writers of message. 
	{	
		private Socket soc;		//Socket for connecting clients to the Server
		private int counter;	//counter to store the number of the clients
		Connection(Socket s, int c) 	//connection constructor
		{ 
			soc = s; 
			counter = c; 
		}
		
		public void run()		//running the connection thread
		{
			try 
			{
				BufferedReader in = new BufferedReader(new InputStreamReader(soc.getInputStream()));
				synchronized(Server.users)	//synchronized ensures that change in the state of "users" array will be visible to all other Threads
				{							//and since users array is a static object in the server class we can call it as "Server.class"
					PrintStream out = Server.users[counter]; //Printstream object to send messages from Server to the Clients
					out.println("Server started to ping ("+ counter +"). Client at "+getTime()+"..." ); //printing the message
					count_down();	//calling count_down method to see the remaining time for the next ping of the Server 
				}
				boolean done = true;	//checks if we are getting inputs from the client(s)
				while (done)	//while we are getting inputs
				{	
					String str = in.readLine();	//getting the input from a client
					if (str == null)	//if there is no input
					{	
						done = false;	//nothing will be done
					}
					else		//if we detect an input
					{	
						Server.message.set("(" + counter + "): " + str);		//we will set the message with the ith client which sends the message
					} 
				}
				soc.close();		//after performing all operations connection socket will be closed	
			}
			catch (Exception e) //if any exception occurs, a message will be printed 
			{	
				System.err.println("Connection error: Client terminated the connection...");
				while(true)
				{
					label[counter].setText("("+counter+"). Client terminated the connection...");
				}
					
			} 
		} 
		
		public String getTime() 	//this method is used to get the current time with the format hours:minutes:seconds
		{
	        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
	        Date date = new Date();
	        return dateFormat.format(date);
	    } 
		

		public void count_down()	//count_down method is used to count down for the next ping of the server
		{	       
			Timer timer = new Timer();	//Setting a timer for counting down
	        TimerTask task = new Task(); 	//setting a timer task to operate what we want to do. Timer task calls Task class
	      
	        timer.scheduleAtFixedRate(task, 100, 1000);	//scheduling the timer due to a specified period
		}												//task will be performed until 100 milliseconds delay and will be repeated every second
		
		public class Task extends TimerTask 	//Task class to perform every seconds
		{
			private int second = 5;		//pinging in every 5 seconds
			private PrintStream out = Server.users[counter];	//used to print server messages on the client side

		    public void run() 	//running the task
		    {
		    	Server.label[counter].setText(second+" seconds remaining for next ping of ("+counter+"). client    -     Time is : "+getTime());
	
				if(second == 5)	//when Server starts pinging a client a message will be printed on the client side
				{
					out.println("Server is pinging ("+ counter +"). Client at "+getTime()+"..." );
				}
				if(second == 0)	//if second gets 0 second will be set to 5 again and server will ping the client(s) continuously.
				{
					second = 5;
				}
				else	//if second is not 0 second will be decreased by 1 after each second
				{
				    second--;
				}
		    }
		}
	}

	private static class Sender extends Thread 		//Sender class is used to broadcast all messages to all users
	{ 
		public void run()		//running the Sender class
		{	
			while(true)			//always repeat the actions inside the block
			{	
				String s = Server.message.get();	//getting the messages of the client(s).
				synchronized(Server.users)
				{	
					for(int i = 0; i < Server.size; i++)
					{
						if(Server.users[i] != null)	//if there is a user on ith socket broadcast the incoming message to all active clients 
						{	
							Server.users[i].println(s);
						}
					}
				}
			}
		}
	}

	private static class Message		//Message class to set and get the incoming messages
	{	
		private String message = null;
		public synchronized void set(String s) //if message is not null set the message
		{	
			try
			{	
				while(message != null) 
				{
					wait();
				}
			}
			catch(InterruptedException e) {}
			message = s;		
			notify();
		}
		
		public synchronized String get()	//if message is not null get the message
		{	
			try
			{	
				while(message == null)
				{
					wait();
				}
			}
			catch(InterruptedException e) 
			{
				System.out.println("Error: "+e);
			}
			String result = message;
			message = null;
			notify();
			return result;
		}
	}	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -