嵌入式系统课设,简单聊天室,无图形化界面,可群聊私聊,传文件

前阵子嵌入式系统实验课,正好在自学java,就用java实现了一个简单的聊天室

由于学校机房的嵌入式系统没有安装图形化界面的相关环境,自行安装比较麻烦,就写了一个没有图形化界面的聊天室系统

简单的分为客户端和服务端,通过socket建立连接,IO流传输数据,下面是代码

Client:

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;



public class Client {

    private Socket socket;
    private DataInputStream dataInputStream=null;
    private DataOutputStream dataOutputStream=null;
    private static DataOutputStream filewrite=null;
    private static DataInputStream fileread=null;
    private static File transferFile=null;
    public static void main(String[] args) {
        Client client = new Client();
        client.start();
    }
    public Client() {
            //用于与服务器建立连接
        try {

            String host="localhost";                //默认为本地ip
            System.out.print("\t     请输入ip:");
            Scanner sc= new Scanner(System.in);     //创建一个Scanner接收ip地址
            host=sc.next();

            System.out.println("正在连接服务端...");
            socket = new Socket(host,6666);    //创建socket套接字,
                                                    // 连接到对应ip的6666号端口
            System.out.println("与服务端建立连接!");

            dataOutputStream=new DataOutputStream(socket.getOutputStream());
            dataInputStream=new DataInputStream(socket.getInputStream());
            //创建输出流,用于发送和接收消息
            System.out.println("\t     可以输入“name:+昵称“的方式设置昵称,否则昵称默认为本地ip");
            System.out.println("\t     可以用“ @ + 对方ip/昵称 @ + 内容 ”的形式私聊对方");
            System.out.println("\t     可以用“file: +文件目录” 的形式传输文件到服务器");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start() {
        try {
            //首先读取服务端发送过来的消息的线程启动
            ServerHandler handler = new ServerHandler();
            Thread t = new Thread(handler);
            t.start();

            Scanner scanner = new Scanner(System.in);

            while(true) {       //一直运行,接收键盘输入信息
                StringBuilder Message = new StringBuilder(scanner.nextLine());
                if(Message.length()>5&&Message.substring(0,5).equals("file:")){
                    //用于判断是否为文件信息
                    dataOutputStream.writeUTF(Message.toString());
                    String filepath=Message.substring(5, Message.length());//获取文件路径
                    transferFile=new File(filepath);                       //创建文件
                    fileread=new DataInputStream(new FileInputStream(transferFile));//创建文件输出流

                    dataOutputStream.writeUTF(transferFile.getName());//输出文件名称
                    System.out.println("发送的文件名为:"+transferFile.getName());

                    long length=transferFile.length();//获取文件名称
                    dataOutputStream.writeLong(length);//输出文件长度
                    System.out.println("发送的文件名长度为"+length+"字节");
                    //使用文件读取流和文件传输流
                    long size=length/2048;
                    if(size<1){
                        byte[] data=new byte[(int) length];
                        fileread.read(data);
                        dataOutputStream.write(data);
                        System.out.println("文件上传完毕");
                    }
                    else{
                        byte[] data=new byte[(int) length];

                        while(size>0){
                            fileread.read(data);
                            dataOutputStream.write(data);
                            size--;
                        }
                        byte[] end=new byte[(int) (length-2048*size)];
                        fileread.read(end);
                        dataOutputStream.write(end);
                        System.out.println("文件上传完毕");
                    }

                    System.out.println("文件"+transferFile+"上传成功!");
                }
                else{
                    dataOutputStream.writeUTF(Message.toString());//如果不是输出文件则为文字信息
                    dataOutputStream.flush();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private class ServerHandler implements Runnable{
        @Override
        public void run() {
            try {
                while(true){
                    //继承Runnable接口,重新定义run方法,用数据接受流接收服务端传来的信息
                        System.out.println(dataInputStream.readUTF());
                }
            } catch (SocketException e) {
                System.out.println("退出聊天室");
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

Server:



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


public class Server {

    private ServerSocket server;
    private List<ClientHandler> clientHandlerList=new ArrayList<>();//创建
    private static String filepath="/root/Pictures/";//设置服务的文件存储位置
    //private static String filepath="C:\\Users\\joy\\Desktop\\local";
    public static void main(String[] args) {

        Server server = new Server();   //主程序,用于调用主函数
        server.start();

    }
    public Server() {
        try {
            System.out.println("正在启动服务端...");

            server = new ServerSocket(6666);//创建服务端Socket
            System.out.println("启动服务端完毕!");
            System.out.println("等待客户端连接...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void start() {
        try {

            while(true) {

                Socket socket = server.accept();//接收客户端连接的socket
                System.out.println("客户端"+socket.getInetAddress().getHostAddress()+"连接了!");
                //启动一个线程处理该客户端交互
                ClientHandler handler = new ClientHandler(socket);//创建一个ClientHandler处理连接的客户端连接的socket
                clientHandlerList.add(handler);//将新添加的ClientHandler加入ClientHandkerList中
                new Thread(handler).start();//启动该线程


            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private class ClientHandler implements Runnable{//定义ClientHandler线程
        private Socket socket;//存储客户端的socket,每个客户端对应一个
        private String host;//存储一个host
        private String name="";//初始化name
        private DataInputStream dataInputStream=null;//文字传输流
        private DataOutputStream dataOutputStream=null;
        private DataInputStream filereader=null;//文件传输流
        private DataOutputStream filewriter=null;
        public ClientHandler(Socket socket) {
            this.socket = socket;
            host = socket.getInetAddress().getHostAddress();//获取客户端对应的socket
        }

        public void run() {
            try {
                dataInputStream=new DataInputStream(socket.getInputStream());//获取文字传输流
                dataOutputStream=new DataOutputStream(socket.getOutputStream());
                while(true){
                    String Message=dataInputStream.readUTF();//接收客户端发来的信息,并对信息进行判断
                    if(Message.length()>=5&&Message.substring(0,5).equals("file:")){//文件的判断
                        String fileName=dataInputStream.readUTF();//获取文件名
                        System.out.println("接受到的文件名为"+fileName);

                        //创建文件
                        File file=new File(filepath+System.getProperties().get("file.separator")+fileName);

                        long length=dataInputStream.readLong();//获取客户端传来的文件长度
                        System.out.println("接收到的文件长度为"+length+"字节");
                        //创建文件传输流
                        filewriter =new DataOutputStream(new FileOutputStream(file,true));

                        //文件传输
                        long size=length/2048;
                        if(size<1){
                            byte[] data=new byte[(int) length];
                            dataInputStream.read(data);
                            filewriter.write(data);
                            System.out.println("文件接收完毕");
                        }
                        else{
                            byte[] data=new byte[2048];
                            byte[] end =new byte[(int)(length-2048*size)];
                            while(size>0){
                                dataInputStream.read(data);
                                filewriter.write(data);
                                size--;
                            }
                            dataInputStream.read(end);
                            filewriter.write(data);
                            System.out.println("文件接收完毕");
                        }
                    }
                    //判断是否为私聊信息
                    else if(Message.length()>1&&Message.substring(0,1).equals("@")){
                        String sourcehost=Message.substring(1,Message.lastIndexOf("@"));//判断第一个字符是否为@
                        String Message01=Message.substring(Message.lastIndexOf("@")+1,Message.length());//获取私聊内容
                        StringBuilder Message02= new StringBuilder("");
                        if(!(name.equals(""))){
                            Message02= new StringBuilder(name + " 私聊对你说:" + Message01);//包装发送的信息
                            System.out.println(name+"对"+sourcehost+"私聊说"+Message01);
                        }
                        else{
                            Message02= new StringBuilder(host + " 私聊对你说:" + Message01);
                            System.out.println(host+"对"+sourcehost+"私聊说"+Message01);
                        }

                        for (int i = 0; i < clientHandlerList.size(); i++) {//遍历clientHandlder
                            if(clientHandlerList.get(i).getHost().equals(sourcehost)||clientHandlerList.get(i).getName().equals(sourcehost)){
                                //判断clientHandlerList中的host或者name是否为私聊对象
                                clientHandlerList.get(i).getDataOutputStream().writeUTF(Message02.toString());
                                break;
                            }
                        }
                    }
                    else if(Message.length()>=5&&Message.substring(0,5).equals("name:")){//判断是否为设置名字
                        setName(Message.substring(5,Message.length()));
                    }
                    else {
                        //普通文字输出
                        StringBuilder realMessage= new StringBuilder("");
                        if(!(name.equals(""))){//对数据进行煲装
                            realMessage= new StringBuilder(name + " 说:" + Message);
                        }
                        else{
                            realMessage= new StringBuilder(host + " 说:" + Message);
                        }

                        System.out.println(realMessage);
                        for (int i = 0; i < clientHandlerList.size(); i++) {
                            clientHandlerList.get(i).getDataOutputStream().writeUTF(realMessage.toString());
                        }
                    }
                }
            } catch (IOException e) {//捕捉IO传输中的异常
                try{

                    socket.close();//如果出现异常,关闭socket
                    clientHandlerList.remove(this);//并从clientHandlerList中移除该clientHanlderList
                }catch (IOException e1){
                    e1.printStackTrace();
                }
            }
            finally {
                try{
                    System.out.println(host+"退出聊天室");//正常退出时的输出
                    dataInputStream.close();
                    dataOutputStream.close();
                    socket.close();
                    clientHandlerList.remove(this);
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }

        public Socket getSocket() {
            return socket;
        }

        public String getHost() {
            return host;
        }

        public DataInputStream getDataInputStream() {
            return dataInputStream;
        }

        public DataOutputStream getDataOutputStream() {
            return dataOutputStream;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

实验结束后,还留下几个bug没有解决,主要是发送文件后会自动退出聊天室,但是由于时间原因就没去深究。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值