Socket程式設計------TCP檔案傳輸(文件、聲音、圖片、視訊和壓縮包等)
阿新 • • 發佈:2019-01-25
本程式是基於TCP穩定傳輸的檔案傳輸,可以相容任何型別任何格式的檔案傳輸。
☆基本思路(客戶端)
客戶端需要明確伺服器的ip地址以及埠,這樣才可以去試著建立連線,如果連線失敗,會出現異常。
連線成功,說明客戶端與服務端建立了通道,那麼通過IO流就可以進行資料的傳輸,而Socket物件已經提供了輸入流和輸出流物件,通過getInputStream(), getOutputStream()獲取即可。
與服務端通訊結束後,關閉Socket。
☆基本思路(伺服器端)
服務端需要明確它要處理的資料是從哪個埠進入的。
當有客戶端訪問時,要明確是哪個客戶端,可通過accept()獲取已連線的客戶端物件,並通過該物件與客戶端通過IO流進行資料傳輸。
當該客戶端訪問結束,關閉該客戶端。
為了相容所有型別的檔案,客戶端在傳送的時候要求先將檔案的字尾名傳送過去,一邊在伺服器端建立正確型別的檔案,這就要求客戶端傳送時要分兩次傳送,第一次傳送字尾名,第二次傳送檔案正文。在第一次傳送完成後要再次一個換行符作為識別符號。
而對於伺服器方,首先需要開多執行緒進行接收資料,因為使用者是不止一個的,且執行緒類應實現Runnable介面。在接收字尾名時接收到換行符之後即建立新檔案,方便後面輸出到該檔案中。
程式碼:
客戶端:
伺服器端:package cn.hncu; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import javax.swing.JFileChooser; public class TcpUploadClient { public static void main(String[] args) { JFileChooser jfc=new JFileChooser(); File file=null; int result=jfc.showOpenDialog(null); if (result==JFileChooser.APPROVE_OPTION){ file=jfc.getSelectedFile(); } //get the suffix int index=file.getName().indexOf("."); String suffix=file.getName().substring(index); byte suffixBuf[]=suffix.getBytes(); Socket socket=null; try { socket=new Socket("192.168.1.106", 8080); //send the suffix first OutputStream out=socket.getOutputStream(); out.write(suffixBuf, 0, suffixBuf.length); out.write('\n'); //send the file BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file)); byte buf[]=new byte[1024]; int len=0; while ((len=bis.read(buf))!=-1){ out.write(buf, 0, len); } socket.shutdownOutput(); out.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
package cn.hncu; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class TcpUploadServer { public static void main(String[] args) { try { ServerSocket server=new ServerSocket(8080); while (true){ Socket socket=server.accept(); new Thread(new SocketThread(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } } } class SocketThread implements Runnable{ private Socket socket; public SocketThread(Socket socket) { this.socket = socket; } @Override public void run() { try { File dir=new File("myFiles"); if (!dir.exists()){ dir.mkdirs(); } InputStream in=socket.getInputStream(); //this variable "count" is used creating many files with different subscripts int count=1; File file=null; int i=0; String suffix; byte buf[]=new byte[1024]; while ((buf[i++]=(byte)in.read())!='\n'){ } suffix=new String(buf,0,i-1); file=new File(dir, "file"+suffix); while (file.exists()){ file=new File(dir, "file("+(count++)+")"+suffix); } int len=0; FileOutputStream fos=new FileOutputStream(file); while ((len=in.read(buf))!=-1){ fos.write(buf, 0, len); } in.close(); fos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }