案例——TCP上傳圖片

  • 2019 年 10 月 19 日
  • 筆記

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) {            }        }    }

結果演示

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