开发者

Java如何通过Socket同时发送文本和文件

开发者 https://www.devze.com 2024-08-11 10:48 出处:网络 作者: 闲不下来的菜鸟
目录第一种方案客户端服务器第二种方案服务端客户端总结这几天在自学Socket网络编程时突然要用到文件和文本同时传输到服务器,
目录
  • 第一种方案
    • 客户端
    • 服务器
  • 第二种方案
    • 服务端
    • 客户端
  • 总结

    这几天在自学Socket网络编程时突然要用到文件和文本同时传输到服务器,

    但是在网上找了半天页找不到具体的结局办法,最后在不断琢磨之下终于解决了这个问题,

    在传输数据时使用的是Java中的ObjectInputStream ObjectOutputStream对象流,

    这个流可以封装复杂的数据在网络中进行传输,

    发送涉及到的类需要实现Serializable接口,是一个标志接口,用于序列化的,没有任何的方法需要实现。

    废话不多说,直接上代码

    第一种方案

    Student类,用于封装数据进行传输和解析

    public class Student implements Serializable {
        private String username;
        private String sex;
        private byte[] file;
        private String filename;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex编程客栈(String sex) {
            this.sex = sex;
        }
    
        public byte[] getFile() {
            return file;
        }
    
        public void setFile(byte[] file) {
            this.file = file;
        }
    
        public String getFilename() {
            return filename;
        }
    
        public void setFilename(String filename) {
            this.filename = filename;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "username='" + username + '\'' +
                    ", sex='" + sex + '\'' +
                    ", filename='" + filename + '\'' +
                    '}';
        }
    }

    客户端

    public class ClientSocket {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1",9999);
    //        获得Socket输出字节流
            OutputStream os = socket.getOutputStream();
            Student student = new Student();
            student.setUsername("765652244");
            student.setSex("男");
    //        获取文件地址
            File file = new File("C:\\Users\\网络杀手\\Desktop\\image\\soft\\bg.png");
    //        将文件名保存到Student中
            student.setFilename(file.getName());
    //        获得文件字节输入流
            FileInputStream fis = new FileInputStream(file);
    //        将文件字节流保存至字节输出缓冲流
            ByteArrayOutputStream bos = new ByteArrayOutputStream(fis.available());
            byte[] b = new byte[1024];
            int len = -1;
            while((len = fis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
    //        将得到的文件字节转换为字节数组
            student.setFile(bos.toByteArray());
    //        将socket输出流进行转换
            ObjectOutputStream oos =new ObjectOutputStream(os);
    //        将对象输出流发送到服务器
            oos.writeObject(student);
            fis.close();
            bos.close();
            oos.flush();
            oos.close();
            System.out.println("发送成功");
        }
    }

    服务器

    public class ServerSocketDome {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ServerSocket serverSocket = new ServerSocket(9999);
    //        监听9999端口,等待客户端连接,如果没有连接,将会一直阻塞
            Socket accept = serverSocket.accept();
    //        获得数据输入流,
            InputStream is = accept.getInputStream();
    //        对数据输入流进行转换
            ObjectInputStream ois = new ObjectInputStream(is);
    //        将获得的数据转换为Studen类
            Student o = (Student)ois.readObject();
            System.out.println("用户名:"+o.getUsername()+"\n"+"性别:"+o.getSex());
            System.out.println("文件名:"+o.getFilename());
    //        将获得的文件保存至磁盘中
            File file = new File("D:\\"+o.getFilename());
    //        获得输出流,准备将内存中的数据写到磁盘
            FileOutputStream fos = new FileOutputStream(file);
    //        将Student类中或的文件字节写入磁盘
            fos.write(o.getFile());
            fos.close();
            serverSocket.close();
            accept.close();
            is.close();
            ois.close();
            System.out.println("保存成功,文件名是:"+o.getFilename()+"\n存在在:"+file+"目录下");
        }
    }

    结果

    Java如何通过Socket同时发送文本和文件

    第二种方案

    不需要封装类,也不需要实现Serializable接口

    服务端

    public class ServerSocketDome1 {
        public static void main(String[] args) {
            try {
                ServerSocket serverSocket = new ServerSocket(9999);
                Socket socket = serverSocket.accept();
    //            对象流
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
    //            读取文件名
                String str = ois.readUTF();
                System.out.println("文件名:"+str);
    //            读取文件大小
                long l = ois.readLong();
                System.out.println("文件大小为:"+l);
    //            这是使用的是缓冲流,避免了文件大时内存溢出
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\"+str)));
                byte[] buffer = new byte[1024*1024];
                int len = -1 ;
                while ((len=ois.read(buffer))!=-1){
                    bos.write(buffer,0,len);
                }
                ois.close();
                bos.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    客户端

    public class Client1 {
        public static void main(String[] args) {
            try {
                Socket soc编程客栈ket = new Socket("127.0.0.1",999www.devze.com9);
                OutputStream os = socket.getOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(os);
                File file = new File("C:\\Users\\网络杀手\\Desktop\\image\\soft\\bg.png");
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);
    //            写入文件名
                oos.writeUTF(file.getName());
    //            获得文件大小
                oos.writeLong(file.length());
                byte[] buffer = new byte[1024*1024];
                int len =-1;
                while ((len=bis.read(buffer))!=-1){
                    oos.write(bufferjavascript,0,len);
                }
                oos.flush();
      www.devze.com          os.close();
                oos.close();
                fis.close();
                bis.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    结果

    Java如何通过Socket同时发送文本和文件

    两种方案中明显是方案二要简便些,但是各有个的优点:

    方案一中发送的数据需要封装,解析时候方便(可以将ByteArrayOutputStream换成BufferedInputStream)如果是多个文件,对Student类中的属性进行一下变更,就能够实现

    第二种方案中需要使用Gson数据封装之后发送和解析,对于负杂的数据时还是要进行封装之后才能发送,否则服务器不好解析。

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号