当前位置: 代码网 > it编程>编程语言>Java > Java如何通过Socket同时发送文本和文件

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

2024年08月10日 Java 我要评论
这几天在自学socket网络编程时突然要用到文件和文本同时传输到服务器,但是在网上找了半天页找不到具体的结局办法,最后在不断琢磨之下终于解决了这个问题,在传输数据时使用的是java中的objectin

这几天在自学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+"目录下");
    }
}

结果

第二种方案

不需要封装类,也不需要实现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 socket = new socket("127.0.0.1",9999);
            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(buffer,0,len);
            }
            oos.flush();
            os.close();
            oos.close();
            fis.close();
            bis.close();
            socket.close();
        } catch (ioexception e) {
            e.printstacktrace();
        }
    }
}

结果

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

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

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com