Java练习项目——在线聊天室

简介: Java练习项目——在线聊天室

Java练习项目——在线聊天室

话不多说,直接上源码:

server端:

import java.io.*;
import java.net.*;
import java.util.*;

public class ChatServer {
   

    boolean stated = false;
    ServerSocket ss = null;
    //创建集合,存储子线程
    List<Client> clients = new ArrayList<>();

    public static void main(String[] args){
   
        new ChatServer().start();
    }

    public void start() {
   
        try {
   
            ss = new ServerSocket(8888);
            stated = true;
        }catch (BindException e) {
   
            System.out.println("running ...");
            System.exit(0);
        }catch (IOException e){
   
            e.printStackTrace();
        }        
        try {
   
            //stated = true;
            while (stated) {
   
                Socket s = ss.accept();
                Client c = new Client(s);
System.out.println("a client connecied!");
                new Thread(c).start();
                clients.add(c);
                //dis.close();
            }
        }catch (IOException e){
   
            e.printStackTrace();
            //System.out.println("closed!");
        }finally {
   
            try {
   
                ss.close();
            } catch (IOException e) {
   
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    }

    class Client implements Runnable {
   
        private Socket s;
        private DataInputStream dis = null;
        private boolean bConnected = false;
        private DataOutputStream dos = null;

        public Client(Socket s) {
   
            this.s = s;
            try {
   
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());
                bConnected = true;
            } catch (IOException e) {
   
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        public void send(String str) {
   
            try {
   
                dos.writeUTF(str);
            } catch (IOException e) {
   
                clients.remove(this);
                System.out.println("对方退出了,list去除!");
            }
        }

        public void run() {
   
            try {
   
                while(bConnected) {
   
                    String str = dis.readUTF();
System.out.println(str);
                    //将接受的数据发送给客户端
                    for (int i=0;i<clients.size();i++) {
   
                        Client c = clients.get(i);
                        c.send(str);
                    }
                }
            } catch (EOFException e) {
   
                System.out.println("Client closed!");
            } catch (IOException e) {
   
                e.printStackTrace();
            } finally {
   
                try {
   
                    if(dis != null) dis.close();
                    if(dos != null) dos.close();
                    if(s != null) s.close();
                } catch (IOException e1) {
   
                    e1.printStackTrace();
                }
            }
        }
    }

}

client端:

//导入Java包
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;


public class ChatClient extends Frame{
   

    boolean bConnected = false;
    //创建成员变量
    DataOutputStream dos = null;
    DataInputStream dis = null;
    //创建socket成员变量
    Socket s = null;
    //TextField单行文本框
    TextField tfText = new TextField();
    // TextArea多行文本框
    TextArea taContent = new TextArea();
    //成员变量
    Thread tRecv = new Thread(new RecvThread());


    public static void main(String[] args) {
   
        //创建对象并调用方法
        ChatClient q = new ChatClient();
        q.launchFrame();
    }

    //创建窗体方法
    public void launchFrame() {
   
        //调整窗口大小
        setLocation(400,300);
        this.setSize(300,300);
        //在窗口的北(上)方,南(下)方添加文本框
        add(tfText, BorderLayout.SOUTH);
        add(taContent, BorderLayout.NORTH);
        //隐藏多余窗口区域
        pack();
        this.addWindowListener(new WindowAdapter(){
   
            //重写WindowAdapter()类的windowClosing方法
            //实现点击关闭终止程序
            @Override
            public void windowClosing(WindowEvent e) {
   
                disconnect();
                System.exit(0);
            }
        });
        //调用Button类中的addActionListener方法
        tfText.addActionListener(new TextListener());
        setVisible(true);
        connect();
        tRecv.start();
    }

    //创建客户端连接服务器方法
    public void connect() {
   
        //使用try/catch语句防止错误异常抛出
        try {
   
            s = new Socket("127.0.0.1",8888);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());
System.out.println("connected!");
            bConnected = true;
        } catch (UnknownHostException e) {
   
            //找不到主机异常
            e.printStackTrace();
        } catch (IOException e) {
   
            //输入错误,连接错误
            //e.printStackTrace();
            System.out.println("输入错误,连接失败");
        }

    }

    //添加清理方法,关闭套接字时将内存等清理
    public void disconnect() {
   
        try {
   
            dos.close();
            dis.close();
            s.close();
        } catch (IOException e) {
   
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }

    //创建继承于ActionListener的类
    private class TextListener implements ActionListener{
   

        //重写actionPerformed方法
        public void actionPerformed(ActionEvent e) {
   
            String str = tfText.getText().trim();
            //taContent.setText(str);
            tfText.setText("");
            try {
   
                dos.writeUTF(str);
                dos.flush();
                //dos.close();
            } catch (IOException e1) {
   
                e1.printStackTrace();
            }
        }

    }

    private class RecvThread implements Runnable {
   

        public void run() {
   
            try {
   
                while (bConnected) {
   
                    String str = dis.readUTF();
                    //System.out.println(str);
                    taContent.setText(taContent.getText() + str + "\n");
                }
            }catch (SocketException e) {
   
                System.out.println("退出了,bye!");
            }catch (IOException e) {
   
                e.printStackTrace();
            }
        }
    }

}

PS:该练习可实现类似在线聊天系统的小功能,本人的第一个的练习,还有很多不足之处,请各位大佬指教。

目录
相关文章
|
9天前
|
Java Maven
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
在Java项目中,启动jar包时遇到“no main manifest attribute”错误,且打包大小明显偏小。常见原因包括:1) Maven配置中跳过主程序打包;2) 缺少Manifest文件或Main-Class属性。解决方案如下:
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
|
6天前
|
存储 Java BI
java怎么统计每个项目下的每个类别的数据
通过本文,我们详细介绍了如何在Java中统计每个项目下的每个类别的数据,包括数据模型设计、数据存储和统计方法。通过定义 `Category`和 `Project`类,并使用 `ProjectManager`类进行管理,可以轻松实现项目和类别的数据统计。希望本文能够帮助您理解和实现类似的统计需求。
42 17
|
28天前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
122 26
|
2月前
|
XML Java 测试技术
从零开始学 Maven:简化 Java 项目的构建与管理
Maven 是一个由 Apache 软件基金会开发的项目管理和构建自动化工具。它主要用在 Java 项目中,但也可以用于其他类型的项目。
63 1
从零开始学 Maven:简化 Java 项目的构建与管理
|
2月前
|
Java
Java项目中高精度数值计算:为何BigDecimal优于Double
在Java项目开发中,涉及金额计算、面积计算等高精度数值操作时,应选择 `BigDecimal` 而非 `Double`。`BigDecimal` 提供任意精度的小数运算、多种舍入模式和良好的可读性,确保计算结果的准确性和可靠性。例如,在金额计算中,`BigDecimal` 可以精确到小数点后两位,而 `Double` 可能因精度问题导致结果不准确。
|
2月前
|
Java Android开发
Eclipse 创建 Java 项目
Eclipse 创建 Java 项目
51 4
|
2月前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
53 3
|
Java Go
哟哟哟,JAVA组装的聊天室,最简单的实现
太码多码码,总是多些感觉~~~ 打了快一个小时啊, 但看着一行一行的出来, 还是有成就感的~~:) VerySimpleChatServer.java import java.io.*; import java.
989 0
|
2天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
32 17
|
12天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者