1.檔案上傳原理(C/S結構:用戶端/伺服器端)
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/*
檔案上傳用戶端
步驟:
1.建立用戶端Socket對象,指定連接配接伺服器的ip位址和端口号
2.建立檔案位元組輸入流FileInputStream類對象fis,綁定用戶端本地源檔案
3.用戶端Socket對象調用getOutputStream方法,擷取用戶端的位元組輸出流對象
4.循環讀(用戶端本地檔案)寫(伺服器)
5.用戶端Socket對象調用getInputStream方法,擷取用戶端的位元組輸入流對象
6.用戶端的位元組輸入流對象調用read方法,讀取伺服器發送回來的響應資訊
7.關閉流,釋放資源
解決問題: 用戶端沒有收到上傳成功的響應資訊
java.net.Socket類
成員方法:
public void shutdownOutput() :
關閉用戶端的位元組輸出流,同時通知伺服器,檔案發送完畢,
相當于給伺服器發送了一個-1
*/
public class UpLoadClient {
public static void main(String[] args) throws IOException {
//1.建立用戶端Socket對象,指定連接配接伺服器的ip位址和端口号
Socket client = new Socket("127.0.0.1", 7777);
//2.建立檔案位元組輸入流FileInputStream類對象fis,綁定用戶端本地源檔案
FileInputStream fis = new FileInputStream("day14\\from\\1.jpg");
//3.用戶端Socket對象調用getOutputStream方法,擷取用戶端的位元組輸出流對象
OutputStream netOs = client.getOutputStream();
//4.循環讀(用戶端本地檔案)寫(伺服器)
int len = 0;
byte[] bs = new byte[1024];
while((len = fis.read(bs))!=-1) {
netOs.write(bs,0,len);
}
//通知伺服器,檔案傳輸完畢,相當于給伺服器發送一個-1
client.shutdownOutput();
//5.用戶端Socket對象調用getInputStream方法,擷取用戶端的位元組輸入流對象
InputStream netIs = client.getInputStream();
//6.用戶端的位元組輸入流對象調用read方法,讀取伺服器發送回來的響應資訊
len = netIs.read(bs);
System.out.println("用戶端收到伺服器的響應資訊: "+new String(bs,0,len));
//7.關閉流,釋放資源
netIs.close();
netOs.close();
client.close();
fis.close();
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/*
檔案上傳伺服器端
步驟:
1.建立伺服器端ServerSocket對象,指定端口号
2.伺服器端ServerSocket對象調用accept方法,擷取連接配接伺服器的Socket對象
3.建立檔案位元組輸出流FileOutputStream類的對象fos,綁定伺服器端本地目标檔案
4.連接配接伺服器的Socket對象調用getInputStream方法,擷取伺服器端的位元組輸入流對象
5.循環讀(用戶端發送的資訊)寫(伺服器端的本地目标檔案)
6.連接配接伺服器的Socket對象調用getOutputStream方法,擷取伺服器端的位元組輸出流對象
7.伺服器端的位元組輸出流對象調用write方法,給用戶端發送響應資訊
8.關閉流,釋放資源
解決問題:
支援多個用戶端上傳,多線程版本的
*/
public class UpLoadServer4 {
public static void main(String[] args) throws IOException {
//1.建立伺服器端ServerSocket對象,指定端口号
ServerSocket server = new ServerSocket(7777);
//死循環
while(true) {
//2.伺服器端ServerSocket對象調用accept方法,擷取連接配接伺服器的Socket對象
Socket client = server.accept();
/*
該方法用來控制服務端的被通路權限
flag: true 表示所有用戶端都可以通路
flag: false 表示隻允許本機的用戶端通路
*/
NetUtils.control(client,false);
//來了一個用戶端,就應該給這個用戶端單獨開啟一個線程
new Thread(new Runnable() {
@Override
public void run() {
try {
//建立一個新的檔案名稱,防止檔案同名時,被覆寫
String newFileName = System.currentTimeMillis() + "_" + new Random().nextInt() + ".jpg";
//3.建立檔案位元組輸出流FileOutputStream類的對象fos,綁定伺服器端本地目标檔案
FileOutputStream fos = new FileOutputStream(new File("day14\\upload",newFileName));
//4.連接配接伺服器的Socket對象調用getInputStream方法,擷取伺服器端的位元組輸入流對象
InputStream netIs = client.getInputStream();
//5.循環讀(用戶端發送的資訊)寫(伺服器端的本地目标檔案)
int len = 0;
byte[] bs = new byte[1024];
while((len = netIs.read(bs))!=-1) {
fos.write(bs,0,len);
}
//6.連接配接伺服器的Socket對象調用getOutputStream方法,擷取伺服器端的位元組輸出流對象
OutputStream netOs = client.getOutputStream();
//7.伺服器端的位元組輸出流對象調用write方法,給用戶端發送響應資訊
netOs.write("上傳成功".getBytes());
//8.關閉流,釋放資源
fos.close();
netIs.close();
netOs.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
//server.close();
}
}