Java基础_19 | 综合练手小项目 —— Java多线程网络聊天室(附源码)
1. 说明
此项目使用到的Java基础知识:
- Java网络通信
- Java多线程
- Java输入输出流
- Java AWT 图形用户界面绘制
每个知识点参考教程:
- Java基础_18 | Java中网络通信程序的设计(url爬虫,TCP/UDP socket程序,socket文件传输程序)
- Java基础_17 | Java多线程程序设计(Java中两种创建线程的方法、多线程之间的同步和互斥)
- Java基础_16 | Java中的输入输出系统(字节流、字符流)
- Java基础_15 | Java中的图形用户界面包AWT使用详解
如果有兴趣,还可以添加网络文件传输功能,参考教程:
- Java基础_18 | Java中网络通信程序的设计(url爬虫,TCP/UDP socket程序,socket文件传输程序)。
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中的端口号转化为整数,创建一个ServerSocketreceieveInput.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 successfullydos = 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』。

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
