Java基礎_19 | 綜合練手小項目 —— Java多線程網絡聊天室(附源碼)

1. 說明

此項目使用到的Java基礎知識:

  • Java網絡通信
  • Java多線程
  • Java輸入輸出流
  • Java AWT 圖形用戶界面繪製

每個知識點參考教程:

如果有興趣,還可以添加網絡文件傳輸功能,參考教程:

2. 服務端源碼

//服務器端
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;

public class Server {

	public static void main(String[] args) {
		ServeMainFrame serveMainFrame = new ServeMainFrame("服務器");	//創建主窗體,標題爲“服務器”
		serveMainFrame.setVisible(true);							//設置主窗體可視化
	}
}
 /*主窗體類*/
class ServeMainFrame extends Frame{
	
	private final int DEFAULT_WDITH = 500,							//窗體默認寬度
			DEFAULT_HEIGHT = 400;									//窗體默認高度
	private Font font = new Font("name",Font.PLAIN,18); 
	private TextField portInput = new TextField("8000",5),			//端口號輸入文本框(默認8000)
			userInput = new TextField("",46);					    //用戶輸入文本框
	private TextArea receieveInput = new TextArea("Welcome to Server!",12,42);	//聊天記錄顯示文本域
	private Panel setPanel = new Panel(),							//設置界面(容器)(容器默認FlowLayout)
			receievePanel = new Panel(),							//接收界面(容器)
			sendPanel = new Panel();								//發送界面(容器)
	private StartButton startButton = new StartButton("Start");
	private ServerSocket ss = null;									//創建服務器套接字(必須要初始化null)	
	private Socket s = null;										//用於接收處理客戶端請求返回的套接字
	DataInputStream dis = null;
	private DataOutputStream dos = null;
	private ServerSendButton serverSendButton = new ServerSendButton("send");
	private ReceieveClient receieveClient =null;
	
	public ServeMainFrame(String title) {	
		super(title);				//調用父類構造方法,生成帶標題的窗體
		addWindowListener(new WindowsClosed());					//添加窗體監聽器,用於關閉窗口
		setBounds(80, 80, DEFAULT_WDITH, DEFAULT_HEIGHT);			//設置窗體位置和大小
		setResizable(false);										//設置用戶不可調整大小
		add(setPanel,"North");//添加端口號設置容器到窗體
			setPanel.add(new Label("Port"));			
			setPanel.add(portInput);
			setPanel.add(startButton);
		add(receievePanel, "Center");  								//添加聊天記錄顯示容器到窗體
			receieveInput.setFont(font);
			receievePanel.add(receieveInput, "Center");
		add(sendPanel, "South");									//添加用戶發送容器到窗體
			sendPanel.add(new Label("say: "));
			sendPanel.add(userInput);
			sendPanel.add(serverSendButton);
	}
	/*啓動按鈕(實現監聽器接口)*/
	class StartButton extends Button implements ActionListener{
		public StartButton(String name) {
			super(name);
			addActionListener(this);  								//自身已經實現監聽器接口,很重要的代碼!!!	
		}
		public void actionPerformed(ActionEvent e) {
			try {
				setEnabled(false);
				ss = new ServerSocket(Integer.valueOf(portInput.getText()));		//利用portInput中的端口號轉化爲整數,創建一個ServerSocket
				receieveInput.append("\nserver starting......");					//顯示server starting......
				s = ss.accept();													//等待客戶端的連接請求
				receieveInput.append("\nclient contect successfully");				//連接成功後顯示client contect successfully
					//創建從客戶端的輸入流
				dos = new DataOutputStream(s.getOutputStream());
				dis =new DataInputStream(s.getInputStream());
				receieveClient = new ReceieveClient();				//創建一個線程,讀取客戶端輸入
				receieveClient.start();;	//啓動該線程
			}
			catch(IOException ioe) {
				receieveInput.append('\n'+ioe.toString());
			}
			finally {
			}
		}
	}
	/*創建一個線程,讀取客戶端輸入*/		//如果實現Runable接口,則會進入死循環
	class ReceieveClient extends Thread{			
		public void run() {
				try {
					String str = dis.readUTF();
					while(str != null) {
							receieveInput.append('\n'+"client say: "+ str);
							str = dis.readUTF();
					}
				}
				catch(IOException ioe) {
					receieveInput.append('\n'+ioe.toString());
				}				
		}
	}
	/*服務器發送按鈕*/
	class ServerSendButton extends Button implements ActionListener{
		public ServerSendButton(String name) {
			super(name);
			addActionListener(this);  										//自身已經實現監聽器接口,很重要的代碼!!!	
		}
		public void actionPerformed(ActionEvent e) {
			try {
				dos.writeUTF(userInput.getText());
				dos.flush();
				receieveInput.append('\n'+"say to client: "+userInput.getText());
				userInput.setText("");
			}
			catch(IOException ioe) {
				receieveInput.append('\n'+ioe.toString());
			}
		}
	}
	/*繼承自Windows監聽器,重寫關閉窗體的方法*/
	class WindowsClosed extends WindowAdapter{
		public void windowClosing(WindowEvent e) {
			System.exit(-1);		//程序終止
		}
	}
}

運行起來效果如下:

3.客戶端源碼

//客戶端
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;

public class Client {

		public static void main(String[] args) {
			ClientMainFrame clientMainFrame = new ClientMainFrame("客戶端");		//創建主窗體,標題爲“服務器”
			clientMainFrame.setVisible(true);									//設置主窗體可視化
		}
	}
	 /*主窗體類*/
	class ClientMainFrame extends Frame {
		private final int DEFAULT_WDITH = 500,									//窗體默認寬度
				DEFAULT_HEIGHT = 400;	//窗體默認高度
		private Font font = new Font("name",Font.PLAIN,18); 
		private TextField ipInput = new TextField("127.0.0.1",8),				//ip地址輸入文本框(默認127.0.0.1)
				portInput = new TextField("8000",5),							//端口號輸入文本框(默認8000)
				userInput = new TextField("",46);							//用戶輸入文本框
		private TextArea receieveInput = new TextArea("Welcome to Client!",12,42);			//聊天記錄顯示文本域
		private Panel setPanel = new Panel(),									//設置界面(容器)(容器默認FlowLayout)
				receievePanel = new Panel(),									//接收界面(容器)
				sendPanel = new Panel();										//發送界面(容器)
		private ConnectButton connectButton = new ConnectButton("Connect");
		private ClientSendButton clienttSendButton = new ClientSendButton("send");
		private Socket s = null;					//用於接收處理客戶端請求返回的套接字
		private DataOutputStream dos = null;				//客戶端輸出流
		private DataInputStream dis = null;
		ReceieveServer receieveServer = null;
		public ClientMainFrame(String title) {	
			super(title);														//調用父類構造方法,生成帶標題的窗體
			addWindowListener(new WindowsClosed());							//添加窗體監聽器,用於關閉窗口
			setBounds(600, 80, DEFAULT_WDITH, DEFAULT_HEIGHT);					//設置窗體位置和大小
			setResizable(false);												//設置用戶不可調整大小
			add(setPanel,"North");												//添加設置容器到窗體
				setPanel.add(new Label("Server IP: "));
				setPanel.add(ipInput);
				setPanel.add(new Label("Port: "));			
				setPanel.add(portInput);
				setPanel.add(connectButton);
			add(receievePanel, "Center");  										//添加聊天記錄顯示容器到窗體
				receieveInput.setFont(font);
				receievePanel.add(receieveInput, "Center");
			add(sendPanel, "South");											//添加用戶發送容器到窗體
				sendPanel.add(new Label("say: "));
				sendPanel.add(userInput);
				sendPanel.add(clienttSendButton);
		}
		/*連接按鈕(實現監聽器接口)*/
		class ConnectButton extends Button implements ActionListener{
			public ConnectButton(String name) {
				super(name);
				addActionListener(this);  										//自身已經實現監聽器接口,很重要的代碼!!!	
			}
			public void actionPerformed(ActionEvent e) {
				try {
					setEnabled(false);
					s = new Socket(ipInput.getText(),Integer.valueOf(portInput.getText()));			//等待客戶端的連接請求
					receieveInput.append("\nserver contect successfully!");		//連接成功後顯示client contect successfully
					dos = new DataOutputStream(s.getOutputStream());
					dis = new DataInputStream(s.getInputStream());
					receieveServer = new ReceieveServer();
					receieveServer.start();
				}
				catch(IOException ioe) {
					receieveInput.append('\n'+ioe.toString());
				}
				finally {
				}
			}
		}
		/*客戶端發送按鈕*/
		class ClientSendButton extends Button implements ActionListener{
			public ClientSendButton(String name) {
				super(name);
				addActionListener(this);  										//自身已經實現監聽器接口,很重要的代碼!!!	
			}
			public void actionPerformed(ActionEvent e) {
				try {
					dos.writeUTF(userInput.getText());
					dos.flush();
					receieveInput.append('\n'+"say to serve: "+userInput.getText());
					userInput.setText("");
				}
				catch(IOException ioe) {
					receieveInput.append('\n'+ioe.toString());
				}
				
			}
		}
		/*創建一個線程,讀取服務器輸入*/
		class ReceieveServer extends Thread{
			public void run() {
					try {
							String str = dis.readUTF();
							while(str != null){
								receieveInput.append('\n'+"serve say: "+str);	
								str = dis.readUTF();
						}
							
					}
					catch(IOException ioe) {
						receieveInput.append('\n'+ioe.toString());
					}				
			}
		}
		/*繼承自Windows監聽器,重寫關閉窗體的方法*/
		 class WindowsClosed extends WindowAdapter{
			public void windowClosing(WindowEvent e) {
					System.exit(-1);		//程序終止
				}
		}
		
		
	}

運行起來效果如下:

4. 運行效果

啓動服務器監聽

客戶端連接服務器


客戶端連接之後在服務端也可以看到:

客戶端發送消息

服務端發送消息


接收更多精彩文章及資源推送,歡迎訂閱我的微信公衆號:『mculover666』

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章