使用TCP實現圖片上傳


  上一篇寫到使用UDP實現文字交互,UDP和TCP各有千秋,所以現在寫一個TCP上傳圖片的demo。

  TCP通信同UDP通信區別在於,UDP中只有發送端和接收端,不區分客戶端與服務器端,計算機之間可以任意地發送數據。TCP通信是嚴格區分客戶端與服務器端的,在通信時,必須先由客戶端去連接服務器端才能實現通信,服務器端不可以主動連接客戶端,並且服務器端程序需要事先啟動,等待客戶端的連接。

  在開發TCP程序時,首先需要創建服務器端程序,JDKjava.net包中提供了一個ServerSocket類。

 

  使用該構造方法在創建ServerSocket對象時,就可以將其綁定到一個指定的端口號上(參數port就是端口號)。

 

  ServerSocket對象負責監聽某台計算機的某個端口號,在創建ServerSocket對象后,需要繼續調用該對象的accept()方法,接收來自客戶端的請求。當執行了accept()方法之后,服務器端程序會發生阻塞,直到客戶端發出連接請求,accept()方法才會返回一個Scoket對象用於和客戶端實現通信,程序才能繼續向下執行。

  ServerSocket對象可以實現服務端程序,但只實現服務器端程序還不能完成通信,此時還需要一個客戶端程序與之交互,為此JDK提供了一個Socket類,用於實現TCP客戶端程序。

 

參數address用於接收一個InetAddress類型的對象,該對象用於封裝一個IP地址。

 

Socket的常用方法,如圖所示。

 

Socket類的常用方法中,getInputStream()getOutStream()方法分別用於獲取輸入流和輸出流。當客戶端和服務端建立連接后,數據是以IO流的形式進行交互的,從而實現通信。

 

下面上代碼

客戶端

 

// 創建Socket對象,連接服務器Socket socket = new Socket("127.0.0.1",8000);
這段代碼只要寫TCP客戶端必定出現

/*
* 實現TCP客戶端,連接到服務器
* 和服務器實現數據交換
* 實現TCP客戶端程序的類java.net.Socket
*
* 構造方法:
* Socket(String host,int port) 傳遞服務器IP和端口號
* 注意:構造方法只要運行,就會和服務器進行連接,連接失敗,拋出異常
* OutputStream getOutputStream() 返回套接字的輸出流
* 作用:將數據輸出,輸出到服務器
* InputStream getInputStream() 返回套接字的輸入流
* 作用:從服務器端讀取數據
* 客戶端服務器數據交換,必須使用套接字對象Socket中的獲取IO流,自己new流,不行
*/

 

package com.lty.wangluotcpPhotoUp;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/*
 * 實現TCP圖片上傳客戶端
 * 實現步驟
 * 1.Socket套接字連接服務器
 * 2.通過Socket獲取字節輸出流,寫圖片
 * 3.使用自己的流對象,讀取圖片數據源
 * 		FileInputStream
 * 4.讀取圖片使用字節輸出流,將圖片寫到服務器
 * 	采用字節數組進行緩沖
 * 5.通過Socket套接字獲取字節輸入流
 * 	讀取服務器發回來的上傳成功
 * 6.關閉資源
 */
public class TCPClient {

	public static void main(String[] args) throws IOException {
		Socket socket = new Socket("127.0.0.1",8000);
		//獲取字節輸出流,圖片寫到服務器
		OutputStream out = socket.getOutputStream();
		// 創建字節輸入流,讀取本機上的數據源圖片
		FileInputStream fis = new FileInputStream("c:\\t.jpg");
		//開始讀寫字節數組
		int len = 0;
		byte[] bytes =new byte[1024];
		while((len = fis.read(bytes))!=-1) {
			out.write(bytes,0,len);
		}
		//給服務器寫終止序列
		socket.shutdownOutput();
		
		//獲取字節輸入流,讀取服務器的上傳成功
		InputStream in = socket.getInputStream();
		len = in.read(bytes);
		System.out.println(new String(bytes,0,len));
		
		fis.close();
		socket.close();
	}

}

 

服務器:

這個demo是多線程的,所以有如下代碼

package com.lty.wangluotcpPhotoUp;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
import java.util.Random;

public class Upload implements Runnable{

	private Socket socket;
	
	public Upload(Socket socket) {this.socket=socket;}
	
	public void run() {
		//通過客戶端連接對象,獲取字節輸入流,獲取客戶端圖片

		try {
			InputStream in = socket.getInputStream();
			//將目的文件夾封裝到File對象
			File upload = new File("d:\\upload");
			if(!upload.exists())
				upload.mkdirs();
			
			//防止文件同名被覆蓋,重新定義文件名字
			//規則: 	域名+毫秒值+6位隨機數
			String filename="itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";
			//創建字節輸出流,將圖片寫入到目的文件夾中
			FileOutputStream fos = new FileOutputStream(upload+File.separator+filename);
			//讀寫字節數組
			byte[] bytes=new byte[1024];
			int len=0;
			while ((len=in.read(bytes))!=-1) {
				fos.write(bytes,0,len);
			}
			//通過客戶端連接對象獲取字節輸出流
			//上次成功寫回到客戶端
			socket.getOutputStream().write("上傳成功".getBytes());
			
			fos.close();
			socket.close();
		} catch (Exception ex) {
		}
	}
}

寫服務器端下面兩端代碼是肯定會出現

ServerSocket server = new ServerSocket(8000);

//調用服務器套接字對象中的方法accept()獲取套接字對象

Socket socket =server.accept();

/*
* 實現TCP服務程序
* 表示服務器程序的類java.net.ServerSocket
* 構造方法:
* SreverSoceket(int port)傳遞端口號
*
* 很重要的事情:必須要獲得客戶端的套接字對象Socket
* Socket accept()
* 服務器可以獲取到客戶端的套接字對象Socket
*
*/

package com.lty.wangluotcpPhotoUp;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPThreadServer {
	public static void main(String[] args)throws IOException {
		ServerSocket server = new ServerSocket(8000);
		while(true) {
		//獲取一個客戶端,必須開啟新線程
		Socket socket=server.accept();
		new Thread(new Upload(socket)).start();
		}
	}
}

  效果圖

網絡編程與IO密不可分,但是IO內容太過繁雜,這里就不一一說了

這里涉及到了多線程請見下回分解

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM