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』

发布了216 篇原创文章 · 获赞 575 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/104382233
今日推荐