TCP上傳圖片
繼續做一個TCP的相關案例,在客戶端上傳一張圖片到服務端,服務端收到圖片後,給客戶端回饋上傳成功信息。
實現細節:
- 對於一些文件的讀取,若文件偏大,可以始用緩衝區去讀取和寫入,可以提高效率
- 服務端面向的是很多用戶,所以必須要開線程來接收
- 如果同一個用戶上傳多張圖片則有可能文件名重複,所以要對文件名做處理,具體在代碼處有註釋
- 客戶端圖片上傳完成後需要給服務端發送結束信息,s.shutdownOutput();
就像是寫入了一個終止符一樣
客戶端
需要在上傳結束的時候寫入終止符告訴服務端上傳結束,可以雙方約定一個終止的符號,也可以用shutdownOutput()方法來傳遞結束信息
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class UploadPicClient {
public static void main(String[] args) throws IOException {
System.out.println("上傳圖片客戶端啓動...");
//1、創建socket
Socket s = new Socket("127.233.24.3", 10018);
//2、讀取源圖片
File picFile = new File("D:\\forio\\download.jpg");
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(picFile));
//3、目的:socket輸出流,發送到服務端
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf)) != -1)
{
out.write(buf, 0, len);
}
//告訴服務端 圖片發送完成,不要在等着讀了
s.shutdownOutput();
//讀取上傳成功字樣
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String info = in.readLine();
System.out.println(info);
//關閉
fis.close();
s.close();
}
}
服務端
服務端需要多線程接收多個客戶的上傳信息,對於有可能存在的文件名重複,添加(1)(2)(3)...加以區分
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadPicServer {
public static void main(String[] args) throws IOException {
System.out.println("上傳圖片服務端啓動...");
// 創建ServerSocket
ServerSocket ss = new ServerSocket(10018);
while (true) {
// 獲取客戶端
Socket s = ss.accept();
// 實現多個客戶端併發上傳,服務器端必須啓動做個線程來完成
new Thread(new UploadPic(s)).start();
}
}
}
class UploadPic implements Runnable {
private Socket s;
public UploadPic(Socket s) {
super();
this.s = s;
}
@Override
public void run() {
try {
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "connected...");
// 寫圖片數據到文件的輸出流
File dir = new File("D:\\forio\\photo");
// 爲了避免重名覆蓋,通過給重名文件進行編號
int count = 1;
File picFile = new File(dir, ip + "(" + count + ")" + ".jpg");
while (picFile.exists()) {
count++;
picFile = new File(dir, ip + "(" + count + ")" + ".jpg");
}
FileOutputStream fos = new FileOutputStream(picFile);
// 讀取客戶端發來的數據
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
// 給客戶端一個回饋信息
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
out.write("上傳成功!"); // 寫完需要刷新一下,或者關閉流
// 關閉資源
out.close();
fos.close();
s.close();
} catch (Exception e) {
}
}
}
結果演示