欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java如何通過Socket同時(shí)發(fā)送文本和文件

 更新時(shí)間:2024年08月10日 15:23:38   作者:閑不下來的菜鳥  
這篇文章主要介紹了Java如何通過Socket同時(shí)發(fā)送文本和文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

這幾天在自學(xué)Socket網(wǎng)絡(luò)編程時(shí)突然要用到文件和文本同時(shí)傳輸?shù)椒?wù)器,

但是在網(wǎng)上找了半天頁找不到具體的結(jié)局辦法,最后在不斷琢磨之下終于解決了這個(gè)問題,

在傳輸數(shù)據(jù)時(shí)使用的是Java中的ObjectInputStream ObjectOutputStream對(duì)象流,

這個(gè)流可以封裝復(fù)雜的數(shù)據(jù)在網(wǎng)絡(luò)中進(jìn)行傳輸,

發(fā)送涉及到的類需要實(shí)現(xiàn)Serializable接口,是一個(gè)標(biāo)志接口,用于序列化的,沒有任何的方法需要實(shí)現(xiàn)。

廢話不多說,直接上代碼

第一種方案

Student類,用于封裝數(shù)據(jù)進(jìn)行傳輸和解析

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輸出字節(jié)流
        OutputStream os = socket.getOutputStream();
        Student student = new Student();
        student.setUsername("765652244");
        student.setSex("男");
//        獲取文件地址
        File file = new File("C:\\Users\\網(wǎng)絡(luò)殺手\\Desktop\\image\\soft\\bg.png");
//        將文件名保存到Student中
        student.setFilename(file.getName());
//        獲得文件字節(jié)輸入流
        FileInputStream fis = new FileInputStream(file);
//        將文件字節(jié)流保存至字節(jié)輸出緩沖流
        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);
        }
//        將得到的文件字節(jié)轉(zhuǎn)換為字節(jié)數(shù)組
        student.setFile(bos.toByteArray());
//        將socket輸出流進(jìn)行轉(zhuǎn)換
        ObjectOutputStream oos =new ObjectOutputStream(os);
//        將對(duì)象輸出流發(fā)送到服務(wù)器
        oos.writeObject(student);
        fis.close();
        bos.close();
        oos.flush();
        oos.close();
        System.out.println("發(fā)送成功");
    }
}

服務(wù)器

public class ServerSocketDome {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ServerSocket serverSocket = new ServerSocket(9999);
//        監(jiān)聽9999端口,等待客戶端連接,如果沒有連接,將會(huì)一直阻塞
        Socket accept = serverSocket.accept();
//        獲得數(shù)據(jù)輸入流,
        InputStream is = accept.getInputStream();
//        對(duì)數(shù)據(jù)輸入流進(jìn)行轉(zhuǎn)換
        ObjectInputStream ois = new ObjectInputStream(is);
//        將獲得的數(shù)據(jù)轉(zhuǎn)換為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());
//        獲得輸出流,準(zhǔn)備將內(nèi)存中的數(shù)據(jù)寫到磁盤
        FileOutputStream fos = new FileOutputStream(file);
//        將Student類中或的文件字節(jié)寫入磁盤
        fos.write(o.getFile());
        fos.close();
        serverSocket.close();
        accept.close();
        is.close();
        ois.close();
        System.out.println("保存成功,文件名是:"+o.getFilename()+"\n存在在:"+file+"目錄下");
    }
}

結(jié)果

第二種方案

不需要封裝類,也不需要實(shí)現(xiàn)Serializable接口

服務(wù)端

public class ServerSocketDome1 {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            Socket socket = serverSocket.accept();
//            對(duì)象流
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
//            讀取文件名
            String str = ois.readUTF();
            System.out.println("文件名:"+str);
//            讀取文件大小
            long l = ois.readLong();
            System.out.println("文件大小為:"+l);
//            這是使用的是緩沖流,避免了文件大時(shí)內(nèi)存溢出
            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\\網(wǎng)絡(luò)殺手\\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();
        }
    }
}

結(jié)果

兩種方案中明顯是方案二要簡(jiǎn)便些,但是各有個(gè)的優(yōu)點(diǎn):

方案一中發(fā)送的數(shù)據(jù)需要封裝,解析時(shí)候方便(可以將ByteArrayOutputStream換成BufferedInputStream)如果是多個(gè)文件,對(duì)Student類中的屬性進(jìn)行一下變更,就能夠?qū)崿F(xiàn)

第二種方案中需要使用Gson數(shù)據(jù)封裝之后發(fā)送和解析,對(duì)于負(fù)雜的數(shù)據(jù)時(shí)還是要進(jìn)行封裝之后才能發(fā)送,否則服務(wù)器不好解析。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mybatis-plus的service通用接口解讀

    Mybatis-plus的service通用接口解讀

    這篇文章主要介紹了Mybatis-plus的service通用接口解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring 依賴注入的幾種方式詳解

    Spring 依賴注入的幾種方式詳解

    本篇文章主要介紹了Spring 依賴注入的幾種方式詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • Java獲取兩個(gè)集合List的交集、補(bǔ)集、并集(相加)和差集(相減)的不同方式

    Java獲取兩個(gè)集合List的交集、補(bǔ)集、并集(相加)和差集(相減)的不同方式

    這篇文章主要給大家介紹了關(guān)于Java獲取兩個(gè)集合List的交集、補(bǔ)集、并集(相加)和差集(相減)的不同方式,在一般操作中對(duì)于list集合取交集、差集、并集,比較簡(jiǎn)單,需要的朋友可以參考下
    2023-08-08
  • springboot實(shí)現(xiàn)執(zhí)行sql語句打印到控制臺(tái)

    springboot實(shí)現(xiàn)執(zhí)行sql語句打印到控制臺(tái)

    這篇文章主要介紹了springboot實(shí)現(xiàn)執(zhí)行sql語句打印到控制臺(tái)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • jxl 導(dǎo)出數(shù)據(jù)到excel的實(shí)例講解

    jxl 導(dǎo)出數(shù)據(jù)到excel的實(shí)例講解

    下面小編就為大家分享一篇jxl 導(dǎo)出數(shù)據(jù)到excel的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • java中ThreadPoolExecutor常識(shí)匯總

    java中ThreadPoolExecutor常識(shí)匯總

    這篇文章主要介紹了java中ThreadPoolExecutor常識(shí)匯總,線程池技術(shù)在并發(fā)時(shí)經(jīng)常會(huì)使用到,java中的線程池的使用是通過調(diào)用ThreadPoolExecutor來實(shí)現(xiàn)的,需要的朋友可以參考下
    2019-06-06
  • Mybatis Mapper接口工作原理實(shí)例解析

    Mybatis Mapper接口工作原理實(shí)例解析

    這篇文章主要介紹了Mybatis Mapper接口工作原理實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 詳解在Spring中如何自動(dòng)創(chuàng)建代理

    詳解在Spring中如何自動(dòng)創(chuàng)建代理

    這篇文章主要介紹了詳解在Spring中如何自動(dòng)創(chuàng)建代理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • SpringBoot整合Ldap的實(shí)現(xiàn)示例

    SpringBoot整合Ldap的實(shí)現(xiàn)示例

    本文主要介紹了SpringBoot整合Ldap的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • Java?SpringBoot操作Redis

    Java?SpringBoot操作Redis

    這篇文章主要介紹了SpringBoot如何操作Redis,文章中有詳細(xì)的代碼示例,有一定的參考價(jià)值,感興趣的同學(xué)可以參考閱讀
    2023-04-04

最新評(píng)論