案例——TCP上傳圖片

TCP上傳圖片

  繼續做一個TCP的相關案例,在客戶端上傳一張圖片到服務端,服務端收到圖片後,給客戶端回饋上傳成功信息。

實現細節:

  • 對於一些文件的讀取,若文件偏大,可以始用緩衝區去讀取和寫入,可以提高效率
  • 服務端面向的是很多用戶,所以必須要開線程來接收
  • 如果同一個用戶上傳多張圖片則有可能文件名重複,所以要對文件名做處理,具體在代碼處有註釋
  • 客戶端圖片上傳完成後需要給服務端發送結束信息,s.shutdownOutput();
    就像是寫入了一個終止符一樣

客戶端

需要在上傳結束的時候寫入終止符告訴服務端上傳結束,可以雙方約定一個終止的符號,也可以用shutdownOutput()方法來傳遞結束信息

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class UploadPicClient {

    public static void main(String[] args) throws IOException {
        System.out.println("上傳圖片客戶端啓動...");
        
        //1、創建socket
        Socket s = new Socket("127.233.24.3", 10018);
        
        //2、讀取源圖片
        File picFile = new File("D:\\forio\\download.jpg");
        BufferedInputStream fis = new BufferedInputStream(new FileInputStream(picFile));
        
        //3、目的:socket輸出流,發送到服務端
        OutputStream out = s.getOutputStream();
        byte[] buf = new byte[1024];
        
        int len = 0;
        while((len = fis.read(buf)) != -1)
        {
            out.write(buf, 0, len);
        }
        
        //告訴服務端   圖片發送完成,不要在等着讀了
        s.shutdownOutput();
        
        //讀取上傳成功字樣
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String info = in.readLine();
        System.out.println(info);
        
        //關閉
        fis.close();
        s.close();
    }
}

服務端

服務端需要多線程接收多個客戶的上傳信息,對於有可能存在的文件名重複,添加(1)(2)(3)...加以區分

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class UploadPicServer {

    public static void main(String[] args) throws IOException {
        System.out.println("上傳圖片服務端啓動...");

        // 創建ServerSocket
        ServerSocket ss = new ServerSocket(10018);

        while (true) {
            // 獲取客戶端
            Socket s = ss.accept();

            // 實現多個客戶端併發上傳,服務器端必須啓動做個線程來完成
            new Thread(new UploadPic(s)).start();

        }
    }
}

class UploadPic implements Runnable {

    private Socket s;

    public UploadPic(Socket s) {
        super();
        this.s = s;
    }

    @Override
    public void run() {

        try {

            String ip = s.getInetAddress().getHostAddress();
            System.out.println(ip + "connected...");

            // 寫圖片數據到文件的輸出流
            File dir = new File("D:\\forio\\photo");
            // 爲了避免重名覆蓋,通過給重名文件進行編號
            int count = 1;
            File picFile = new File(dir, ip + "(" + count + ")" + ".jpg");
            while (picFile.exists()) {
                count++;
                picFile = new File(dir, ip + "(" + count + ")" + ".jpg");
            }

            FileOutputStream fos = new FileOutputStream(picFile);

            // 讀取客戶端發來的數據
            InputStream in = s.getInputStream();
            byte[] buf = new byte[1024];
            int len = 0;

            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }

            // 給客戶端一個回饋信息
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            out.write("上傳成功!"); // 寫完需要刷新一下,或者關閉流

            // 關閉資源
            out.close();
            fos.close();
            s.close();

        } catch (Exception e) {

        }

    }

}

結果演示

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章