国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java Socket實現文件傳輸示例代碼

2019-11-26 13:10:46
字體:
來源:轉載
供稿:網友

最近學Socket學上癮了,就寫了一個簡單的文件傳輸程序。

客戶端設計思路:客戶端與服務端建立連接,選擇客戶端本地文件,先將文件名及大小等屬性發送給服務端,再將文件通過流的方式傳輸給服務端。傳輸的進度打印到控制臺中,直到傳輸完成。

服務端設計思路:服務端接收客戶端的請求(阻塞式),每接收到一個客戶端請求連接后,就新開一個處理文件的線程,開始寫入流,將文件到服務器的指定目錄下,并與傳輸過來的文件同名。
下面是客戶端和服務端的代碼實現:

客戶端代碼:

import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.net.Socket;  /**  * 文件傳輸Client端<br>  * 功能說明:  *  * @author 大智若愚的小懂  * @Date 2016年09月01日  * @version 1.0  */ public class FileTransferClient extends Socket {    private static final String SERVER_IP = "127.0.0.1"; // 服務端IP   private static final int SERVER_PORT = 8899; // 服務端端口    private Socket client;    private FileInputStream fis;    private DataOutputStream dos;    /**    * 構造函數<br/>    * 與服務器建立連接    * @throws Exception    */   public FileTransferClient() throws Exception {     super(SERVER_IP, SERVER_PORT);     this.client = this;     System.out.println("Cliect[port:" + client.getLocalPort() + "] 成功連接服務端");   }    /**    * 向服務端傳輸文件    * @throws Exception    */   public void sendFile() throws Exception {     try {       File file = new File("E://JDK1.6中文參考手冊(JDK_API_1_6_zh_CN).CHM");       if(file.exists()) {         fis = new FileInputStream(file);         dos = new DataOutputStream(client.getOutputStream());          // 文件名和長度         dos.writeUTF(file.getName());         dos.flush();         dos.writeLong(file.length());         dos.flush();          // 開始傳輸文件         System.out.println("======== 開始傳輸文件 ========");         byte[] bytes = new byte[1024];         int length = 0;         long progress = 0;         while((length = fis.read(bytes, 0, bytes.length)) != -1) {           dos.write(bytes, 0, length);           dos.flush();           progress += length;           System.out.print("| " + (100*progress/file.length()) + "% |");         }         System.out.println();         System.out.println("======== 文件傳輸成功 ========");       }     } catch (Exception e) {       e.printStackTrace();     } finally {       if(fis != null)         fis.close();       if(dos != null)         dos.close();       client.close();     }   }    /**    * 入口    * @param args    */   public static void main(String[] args) {     try {       FileTransferClient client = new FileTransferClient(); // 啟動客戶端連接       client.sendFile(); // 傳輸文件     } catch (Exception e) {       e.printStackTrace();     }   }  } 

服務端代碼:

import java.io.DataInputStream; import java.io.File; import java.io.FileOutputStream; import java.math.RoundingMode; import java.net.ServerSocket; import java.net.Socket; import java.text.DecimalFormat;  /**  * 文件傳輸Server端<br>  * 功能說明:  *  * @author 大智若愚的小懂  * @Date 2016年09月01日  * @version 1.0  */ public class FileTransferServer extends ServerSocket {    private static final int SERVER_PORT = 8899; // 服務端端口    private static DecimalFormat df = null;    static {     // 設置數字格式,保留一位有效小數     df = new DecimalFormat("#0.0");     df.setRoundingMode(RoundingMode.HALF_UP);     df.setMinimumFractionDigits(1);     df.setMaximumFractionDigits(1);   }    public FileTransferServer() throws Exception {     super(SERVER_PORT);   }    /**    * 使用線程處理每個客戶端傳輸的文件    * @throws Exception    */   public void load() throws Exception {     while (true) {       // server嘗試接收其他Socket的連接請求,server的accept方法是阻塞式的       Socket socket = this.accept();       /**        * 我們的服務端處理客戶端的連接請求是同步進行的, 每次接收到來自客戶端的連接請求后,        * 都要先跟當前的客戶端通信完之后才能再處理下一個連接請求。 這在并發比較多的情況下會嚴重影響程序的性能,        * 為此,我們可以把它改為如下這種異步處理與客戶端通信的方式        */       // 每接收到一個Socket就建立一個新的線程來處理它       new Thread(new Task(socket)).start();     }   }    /**    * 處理客戶端傳輸過來的文件線程類    */   class Task implements Runnable {      private Socket socket;      private DataInputStream dis;      private FileOutputStream fos;      public Task(Socket socket) {       this.socket = socket;     }      @Override     public void run() {       try {         dis = new DataInputStream(socket.getInputStream());          // 文件名和長度         String fileName = dis.readUTF();         long fileLength = dis.readLong();         File directory = new File("D://FTCache");         if(!directory.exists()) {           directory.mkdir();         }         File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);         fos = new FileOutputStream(file);          // 開始接收文件         byte[] bytes = new byte[1024];         int length = 0;         while((length = dis.read(bytes, 0, bytes.length)) != -1) {           fos.write(bytes, 0, length);           fos.flush();         }         System.out.println("======== 文件接收成功 [File Name:" + fileName + "] [Size:" + getFormatFileSize(fileLength) + "] ========");       } catch (Exception e) {         e.printStackTrace();       } finally {         try {           if(fos != null)             fos.close();           if(dis != null)             dis.close();           socket.close();         } catch (Exception e) {}       }     }   }    /**    * 格式化文件大小    * @param length    * @return    */   private String getFormatFileSize(long length) {     double size = ((double) length) / (1 << 30);     if(size >= 1) {       return df.format(size) + "GB";     }     size = ((double) length) / (1 << 20);     if(size >= 1) {       return df.format(size) + "MB";     }     size = ((double) length) / (1 << 10);     if(size >= 1) {       return df.format(size) + "KB";     }     return length + "B";   }    /**    * 入口    * @param args    */   public static void main(String[] args) {     try {       FileTransferServer server = new FileTransferServer(); // 啟動服務端       server.load();     } catch (Exception e) {       e.printStackTrace();     }   } } 

測試的結果(客戶端):

測試的結果(服務端):

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 崇左市| 德化县| 息烽县| 延安市| 嘉峪关市| 海伦市| 保山市| 望江县| 临邑县| 中西区| 获嘉县| 绍兴县| 巴楚县| 东阳市| 璧山县| 白玉县| 怀远县| 贵德县| 鄄城县| 神木县| 塔河县| 嘉荫县| 祁东县| 平安县| 甘孜县| 江城| 容城县| 玉环县| 榕江县| 汕尾市| 云安县| 集安市| 青冈县| 岑溪市| 枣强县| 平和县| 五原县| 岢岚县| 南和县| 齐河县| 武平县|