用Java實現簡單的檔案上傳伺服器和客戶端
阿新 • • 發佈:2019-02-19
/** * 使用TCP協議實現上傳功能的伺服器端 * 思路: * 新建ServerSocket * 等待客戶端連線 * 連線上後開啟子執行緒,把連接獲取的Socket傳給子執行緒 * 迴圈進行 * @author yajun * */ public class UploadServer { public static void main(String[] args) { UploadServer server=new UploadServer(); UploadThread command=new UploadThread(); server.start(command); } /** * 功能:接受連線,開啟子執行緒,迴圈 * @param command 用於下載的子執行緒物件,該物件實現了Runnable介面 */ private void start(UploadThread command){ //區域性變數 ServerSocket serverSocket = null; Socket transSocket; //業務邏輯 try { serverSocket=new ServerSocket(55555); while(true){ System.out.println("等待連線……"); transSocket=serverSocket.accept(); int i=0; i++; System.out.println("第"+i+"個連線"); //用不用在下載完後關閉執行緒呢??? command.setSocket(transSocket); Executors.newFixedThreadPool(5).execute(command); } //異常捕獲 } catch (IOException e) { e.printStackTrace(); //關閉資源 } finally{ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } }//End of try }//End of connect @Test public void testConnect() { //測試任務:先執行伺服器端,然後多次執行客戶端,伺服器段可以不斷建立子執行緒,則測試成功 //測試準備:構造一個執行緒,用於模擬下載執行緒 UploadThread command=new UploadThread(); start(command); } @Test public void testDown() throws IOException { byte[] buf; ByteArrayInputStream bis; String str="canglaoshi.avi\ncontent,content,content"; buf=str.getBytes(); bis=new ByteArrayInputStream(buf); UploadThread ut=new UploadThread(); ut.down(bis); } } //完成各個傳輸任務的子執行緒 class UploadThread implements Runnable{ Socket socket; public UploadThread(){} public UploadThread(Socket socket){ this.socket=socket; } @Override public void run() { InputStream in; try { in = socket.getInputStream(); down(in); //異常處理 } catch (IOException e) { e.printStackTrace(); } finally{ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } //測試程式碼 /*try { Thread.sleep(5000); System.out.println(Thread.currentThread().getName()+",複製完畢"); } catch (InterruptedException e) { e.printStackTrace(); }*/ }//End of run public void setSocket(Socket socket){ this.socket=socket; } //下載方法 /** * 目標:把InputStream中的資料寫入到本地 * 思路: * 1.獲取輸入流,最好傳入輸入流,而不是直接從Socket獲取,傳入有利用單元測試 * 2.從輸入流中讀到檔名 * 3.新建檔案和檔案輸出流 * 4.從輸入流中讀到檔案內容到檔案輸出流 * 5. * @throws IOException */ public void down(InputStream in) throws IOException{ //區域性變數 char ch; char[] nameArr=new char[256]; byte[] buf=new byte[1024]; String name=""; OutputStream out = null; //業務邏輯 try { //第一步:獲取檔名,構造檔案輸出流 int i=0; while((ch=(char) in.read())!='\n'){ nameArr[i++]= ch; } //name=nameArr.toString();//這句話無法將字元陣列轉換為字串,需用下面的語句 name=new String(nameArr); System.out.println("要下載的檔案為:"+name); out=new FileOutputStream("src\\down\\"+name); //第二步:將輸入流中的其他內容寫入到檔案 int len; while((len=in.read(buf))!=-1){ out.write(buf,0,len); } out.flush(); //異常捕獲 } catch (IOException e) { e.printStackTrace(); //關閉資源 }finally{ //疑問:兩個捕獲可不可以放到一塊呢,怎樣處理關閉流時的異常最好呢? in.close(); out.close(); } //除錯 System.out.println(name); } }//End of UploadThread