1. 程式人生 > >Socket程式設計------TCP檔案傳輸(文件、聲音、圖片、視訊和壓縮包等)

Socket程式設計------TCP檔案傳輸(文件、聲音、圖片、視訊和壓縮包等)

本程式是基於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();
		}
	}
}