java實現客戶端向伺服器傳送檔案的操作
阿新 • • 發佈:2019-01-03
伺服器原始碼:
import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * * 檔名:ServerReceive.java * 實現功能:作為伺服器接收客戶端傳送的檔案 * * 具體實現過程: * 1、建立SocketServer,等待客戶端的連線 * 2、當有客戶端連線的時候,按照雙方的約定,這時要讀取一行資料 * 其中儲存客戶端要傳送的檔名和檔案大小資訊 * 3、根據檔名在本地建立檔案,並建立好流通訊 * 4、迴圈接收資料包,將資料包寫入檔案 * 5、當接收資料的長度等於提前檔案發過來的檔案長度,即表示檔案接收完畢,關閉檔案 * 6、檔案接收工作結束 * * * 【注:此程式碼僅為演示客戶端與伺服器傳送檔案使用, * 每一個數據包之前沒有檔案協議命令 * 具體的協議傳輸和檔案傳出的使用階段可根據自己程式自行放置】 * * * 作者:小菜鳥 * 建立時間:2014-08-19 * * */ public class ServerReceive { public static void main(String[] args) { /**與伺服器建立連線的通訊控制代碼*/ ServerSocket ss = null; Socket s = null; /**定義用於在接收後在本地建立的檔案物件和檔案輸出流物件*/ File file = null; FileOutputStream fos = null; /**定義輸入流,使用socket的inputStream對資料包進行輸入*/ InputStream is = null; /**定義byte陣列來作為資料包的儲存資料包*/ byte[] buffer = new byte[4096 * 5]; /**用來接收檔案傳送請求的字串*/ String comm = null; /**建立socekt通訊,等待伺服器進行連線*/ try { ss = new ServerSocket(4004); s = ss.accept(); } catch (IOException e) { e.printStackTrace(); } /**讀取一行客戶端傳送過來的約定資訊*/ try { InputStreamReader isr = new InputStreamReader(s.getInputStream()); BufferedReader br = new BufferedReader(isr); comm = br.readLine(); } catch (IOException e) { System.out.println("伺服器與客戶端斷開連線"); } /**開始解析客戶端傳送過來的請求命令*/ int index = comm.indexOf("/#"); /**判斷協議是否為傳送檔案的協議*/ String xieyi = comm.substring(0, index); if(!xieyi.equals("111")){ System.out.println("伺服器收到的協議碼不正確"); return; } /**解析出檔案的名字和大小*/ comm = comm.substring(index + 2); index = comm.indexOf("/#"); String filename = comm.substring(0, index).trim(); String filesize = comm.substring(index + 2).trim(); /**建立空檔案,用來進行接收檔案*/ file = new File(filename); if(!file.exists()){ try { file.createNewFile(); } catch (IOException e) { System.out.println("伺服器端建立檔案失敗"); } }else{ /**在此也可以詢問是否覆蓋*/ System.out.println("本路徑已存在相同檔案,進行覆蓋"); } /**【以上就是客戶端程式碼中寫到的伺服器的準備部分】*/ /** * 伺服器接收檔案的關鍵程式碼*/ try { /**將檔案包裝到檔案輸出流物件中*/ fos = new FileOutputStream(file); long file_size = Long.parseLong(filesize); is = s.getInputStream(); /**size為每次接收資料包的長度*/ int size = 0; /**count用來記錄已接收到檔案的長度*/ long count = 0; /**使用while迴圈接收資料包*/ while(count < file_size){ /**從輸入流中讀取一個數據包*/ size = is.read(buffer); /**將剛剛讀取的資料包寫到本地檔案中去*/ fos.write(buffer, 0, size); fos.flush(); /**將已接收到檔案的長度+size*/ count += size; System.out.println("伺服器端接收到資料包,大小為" + size); } } catch (FileNotFoundException e) { System.out.println("伺服器寫檔案失敗"); } catch (IOException e) { System.out.println("伺服器:客戶端斷開連線"); }finally{ /** * 將開啟的檔案關閉 * 如有需要,也可以在此關閉socket連線 * */ try { if(fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); }//catch (IOException e) }//finally }//public static void main(String[] args) }//public class ServerReceive
客戶端原始碼:
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; /** * * 檔名:ClientSend.java * 實現功能:作為客戶端向伺服器傳送一個檔案 * * 具體實現過程: * 1、建立與伺服器端的連線,IP:127.0.0.1, port:4004 * 2、將檔案的名字和大小通過自定義的檔案傳輸協議,傳送到伺服器 * 3、迴圈讀取本地檔案,將檔案打包傳送到資料輸出流中 * 4、關閉檔案,結束傳輸 * * 【注:此程式碼僅為演示客戶端與伺服器傳送檔案使用, * 每一個數據包之前沒有檔案協議命令 * 具體的協議傳輸和檔案傳出的使用階段可根據自己程式自行放置】 * * * 作者:小菜鳥 * 建立時間:2014-08-19 * * */ public class ClientSend { public static void main(String[] args) { /**與伺服器建立連線的通訊控制代碼*/ Socket s = null; /**定義檔案物件,即為要傳送的檔案 * 如果使用絕對路徑,不要忘記使用'/'和'\'的區別 * 具體區別,請讀者自行查詢 * */ File sendfile = new File("API.CHM"); /**定義檔案輸入流,用來開啟、讀取即將要傳送的檔案*/ FileInputStream fis = null; /**定義byte陣列來作為資料包的儲存資料包*/ byte[] buffer = new byte[4096 * 5]; /**定義輸出流,使用socket的outputStream對資料包進行輸出*/ OutputStream os = null; /**檢查要傳送的檔案是否存在*/ if(!sendfile.exists()){ System.out.println("客戶端:要傳送的檔案不存在"); return; } /**與伺服器建立連線*/ try { s = new Socket("127.0.0.1", 4004); }catch (IOException e) { System.out.println("未連線到伺服器"); } /**用檔案物件初始化fis物件 * 以便於可以提取出檔案的大小 * */ try { fis = new FileInputStream(sendfile); } catch (FileNotFoundException e1) { e1.printStackTrace(); } /**首先先向伺服器傳送關於檔案的資訊,以便於伺服器進行接收的相關準備工作 * 具體的準備工作,請檢視伺服器程式碼。 * * 傳送的內容包括:傳送檔案協議碼(此處為111)/#檔名(帶字尾名)/#檔案大小 * */ try { PrintStream ps = new PrintStream(s.getOutputStream()); ps.println("111/#" + sendfile.getName() + "/#" + fis.available()); ps.flush(); } catch (IOException e) { System.out.println("伺服器連線中斷"); } /** * 此處睡眠2s,等待伺服器把相關的工作準備好 * 也是為了保證網路的延遲 * 讀者可自行選擇新增此程式碼 * */ try { Thread.sleep(2000); } catch (InterruptedException e1) { e1.printStackTrace(); } /**之前的準備工作結束之後 * 下面就是檔案傳輸的關鍵程式碼 * */ try { /**獲取socket的OutputStream,以便向其中寫入資料包*/ os = s.getOutputStream(); /** size 用來記錄每次讀取檔案的大小*/ int size = 0; /**使用while迴圈讀取檔案,直到檔案讀取結束*/ while((size = fis.read(buffer)) != -1){ System.out.println("客戶端傳送資料包,大小為" + size); /**向輸出流中寫入剛剛讀到的資料包*/ os.write(buffer, 0, size); /**重新整理一下*/ os.flush(); } } catch (FileNotFoundException e) { System.out.println("客戶端讀取檔案出錯"); } catch (IOException e) { System.out.println("客戶端輸出檔案出錯"); }finally{ /** * 將開啟的檔案關閉 * 如有需要,也可以在此關閉socket連線 * */ try { if(fis != null) fis.close(); } catch (IOException e) { System.out.println("客戶端檔案關閉出錯"); }//catch (IOException e) }//finally }//public static void main(String[] args) }//public class ClientSend