1、網路三要素及傳輸協議 2、實現UDP協議的發送端和接收端 3、實現TCP協議的客戶端和伺服器 4、TCP上傳文件案例 ...
今日內容介紹
1、網路三要素及傳輸協議
2、實現UDP協議的發送端和接收端
3、實現TCP協議的客戶端和伺服器
4、TCP上傳文件案例
01網路模型
*A:網路模型
TCP/IP協議中的四層分別是應用層、傳輸層、網路層和鏈路層,每層分別負責不同的通信功能,接下來針對這四層進行詳細地講解。
鏈路層:鏈路層是用於定義物理傳輸通道,通常是對某些網路連接設備的驅動協議,例如針對光纖、網線提供的驅動。
網路層:網路層是整個TCP/IP協議的核心,它主要用於將傳輸的數據進行分組,將分組數據發送到目標電腦或者網路。
傳輸層:主要使網路程式進行通信,在進行網路通信時,可以採用TCP協議,也可以採用UDP協議。
應用層:主要負責應用程式的協議,例如HTTP協議、FTP協議等。
02IP地址
*A:IP地址
在TCP/IP協議中,這個標識號就是IP地址,它可以唯一標識一臺電腦,
目前,IP地址廣泛使用的版本是IPv4,它是由4個位元組大小的二進位數來表示,如:00001010000000000000000000000001。
由於二進位形式表示的IP地址非常不便記憶和處理,因此通常會將IP地址寫成十進位的形式,
每個位元組用一個十進位數字(0-255)表示,數字間用符號“.”分開,如 “192.168.1.100”
127.0.0.1 為本地主機地址(本地迴環地址)
03埠號
*A:埠號
通過IP地址可以連接到指定電腦,但如果想訪問目標電腦中的某個應用程式,還需要指定埠號。
在電腦中,不同的應用程式是通過埠號區分的。
埠號是用兩個位元組(16位的二進位數)表示的,它的取值範圍是0~65535,
其中,0~1023之間的埠號用於一些知名的網路服務和應用,用戶的普通應用程式需要使用1024以上的埠號,從而避免埠號被另外一個應用或服務所占用
04InetAddress類
*A:InetAddress類
/*
* 表示互聯網中的IP地址
* java.net.InetAddress
* 靜態方法
* static InetAddress getLocalHost() LocalHost本地主機
* 返回本地主機,返回值InetAddress對象
*
* static InetAddress getByName(String hostName)傳遞主機名,獲取IP地址對象
*
* 非靜態方法
* String getHoustAddress()獲取主機IP地址
* String getHoustName()獲取主機名
*
*/
public class InetAddressDemo {
public static void main(String[] args)throws UnknownHostException {
function_1();
}
/*
* static InetAddress getByName(String hostName)傳遞主機名,獲取IP地址對象
*/
public static void function_1()throws UnknownHostException {
InetAddress inet = InetAddress.getByName("www.baidu.com");
System.out.println(inet);
}
/*
* static InetAddress getLocalHost() LocalHost本地主機
*/
public static void function() throws UnknownHostException{
InetAddress inet = InetAddress.getLocalHost();
//輸出結果就是主機名,和 IP地址
System.out.println(inet.toString());
String ip = inet.getHostAddress();
String name = inet.getHostName();
System.out.println(ip+" "+name);
/*String host = inet.toString();
String[] str = host.split("/");
for(String s : str){
System.out.println(s);
}*/
}
}
05UDP協議
A:UDP協議
a:UDP協議概述:
UDP是無連接通信協議,即在數據傳輸時,數據的發送端和接收端不建立邏輯連接。
簡單來說,當一臺電腦向另外一臺電腦發送數據時,發送端不會確認接收端是否存在,就會發出數據,同樣接收端在收到數據時,也不會向發送端反饋是否收到數據。
b:UDP協議特點:
由於使用UDP協議消耗資源小,通信效率高,所以通常都會用於音頻、視頻和普通數據的傳輸例如視頻會議都使用UDP協議,
因為這種情況即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。
06TCP協議
*A:TCP協議
TCP協議是面向連接的通信協議,即在傳輸數據前先在發送端和接收端建立邏輯連接,然後再傳輸數據,它提供了兩台電腦之間可靠無差錯的數據傳輸。
在TCP連接中必須要明確客戶端與伺服器端,
由客戶端向服務端發出連接請求,每次連接的創建都需要經過“三次握手”。
第一次握手,客戶端向伺服器端發出連接請求,等待伺服器確認
第二次握手,伺服器端向客戶端回送一個響應,通知客戶端收到了連接請求
第三次握手,客戶端再次向伺服器端發送確認信息,確認連接
07數據包和發送對象介紹
*A:數據包和發送對象介紹:
DatagramPacket數據包的作用就如同是“集裝箱”,
可以將發送端或者接收端的數據封裝起來。然而運輸貨物只有“集裝箱”是不夠的,還需要有碼頭。
在程式中需要實現通信只有DatagramPacket數據包也同樣不行,為此JDK中提供的一個DatagramSocket類。
DatagramSocket類的作用就類似於碼頭,使用這個類的實例對象就可以發送和接收DatagramPacket數據包
DatagramPacket:封裝數據
DatagramSocket:發送DatagramPacket
08UDP發送端
*A:UDP發送端
/*
* 實現UDP協議的發送端:
* 實現封裝數據的類 java.net.DatagramPacket 將你的數據包裝
* 實現數據傳輸的類 java.net.DatagramSocket 將數據包發出去
*
* 實現步驟:
* 1. 創建DatagramPacket對象,封裝數據, 接收的地址和埠
* 2. 創建DatagramSocket
* 3. 調用DatagramSocket類方法send,發送數據包
* 4. 關閉資源
*
* DatagramPacket構造方法:
* DatagramPacket(byte[] buf, int length, InetAddress address, int port)
*
* DatagramSocket構造方法:
* DatagramSocket()空參數
* 方法: send(DatagramPacket d)
*
*/
public class UDPSend {
public static void main(String[] args) throws IOException{
//創建數據包對象,封裝要發送的數據,接收端IP,埠
byte[] date = "你好UDP".getBytes();
//創建InetAddress對象,封裝自己的IP地址
InetAddress inet = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(date, date.length, inet,6000);
//創建DatagramSocket對象,數據包的發送和接收對象
DatagramSocket ds = new DatagramSocket();
//調用ds對象的方法send,發送數據包
ds.send(dp);
//關閉資源
ds.close();
}
}
09UDP接收端
*A:UDP接收端
/*
* 實現UDP接收端
* 實現封裝數據包 java.net.DatagramPacket 將數據接收
* 實現輸出傳輸 java.net.DatagramSocket 接收數據包
*
* 實現步驟:
* 1. 創建DatagramSocket對象,綁定埠號
* 要和發送端埠號一致
* 2. 創建位元組數組,接收發來的數據
* 3. 創建數據包對象DatagramPacket
* 4. 調用DatagramSocket對象方法
* receive(DatagramPacket dp)接收數據,數據放在數據包中
* 5. 拆包
* 發送的IP地址
* 數據包對象DatagramPacket方法getAddress()獲取的是發送端的IP地址對象
* 返回值是InetAddress對象
* 接收到的位元組個數
* 數據包對象DatagramPacket方法 getLength()
* 發送方的埠號
* 數據包對象DatagramPacket方法 getPort()發送埠
* 6. 關閉資源
*/
public class UDPReceive {
public static void main(String[] args)throws IOException {
//創建數據包傳輸對象DatagramSocket 綁定埠號
DatagramSocket ds = new DatagramSocket(6000);
//創建位元組數組
byte[] data = new byte[1024];
//創建數據包對象,傳遞位元組數組
DatagramPacket dp = new DatagramPacket(data, data.length);
//調用ds對象的方法receive傳遞數據包
ds.receive(dp);
}
}
10UDP接收端的拆包
*A:UDP接收端的拆包
/*
* 實現UDP接收端
* 實現封裝數據包 java.net.DatagramPacket 將數據接收
* 實現輸出傳輸 java.net.DatagramSocket 接收數據包
*
* 實現步驟:
* 1. 創建DatagramSocket對象,綁定埠號
* 要和發送端埠號一致
* 2. 創建位元組數組,接收發來的數據
* 3. 創建數據包對象DatagramPacket
* 4. 調用DatagramSocket對象方法
* receive(DatagramPacket dp)接收數據,數據放在數據包中
* 5. 拆包
* 發送的IP地址
* 數據包對象DatagramPacket方法getAddress()獲取的是發送端的IP地址對象
* 返回值是InetAddress對象
* 接收到的位元組個數
* 數據包對象DatagramPacket方法 getLength()
* 發送方的埠號
* 數據包對象DatagramPacket方法 getPort()發送埠
* 6. 關閉資源
*/
public class UDPReceive {
public static void main(String[] args)throws IOException {
//創建數據包傳輸對象DatagramSocket 綁定埠號
DatagramSocket ds = new DatagramSocket(6000);
//創建位元組數組
byte[] data = new byte[1024];
//創建數據包對象,傳遞位元組數組
DatagramPacket dp = new DatagramPacket(data, data.length);
//調用ds對象的方法receive傳遞數據包
ds.receive(dp);
//獲取發送端的IP地址對象
String ip=dp.getAddress().getHostAddress();
//獲取發送的埠號
int port = dp.getPort();
//獲取接收到的位元組個數
int length = dp.getLength();
System.out.println(new String(data,0,length)+"..."+ip+":"+port);
ds.close();
}
}
11鍵盤輸入的聊天
*A:鍵盤輸入的聊天
*a:發送端:
/*
* 實現UDP發送,鍵盤輸入的形式
* 輸入完畢,發送給接收端
*/
public class UDPSend {
public static void main(String[] args) throws IOException{
Scanner sc = new Scanner(System.in);
DatagramSocket ds = new DatagramSocket();
InetAddress inet = InetAddress.getByName("127.0.0.1");
while(true){
String message = sc.nextLine();
/*if("886".equals(message)){
break;
}*/
byte[] date = message.getBytes();
DatagramPacket dp = new DatagramPacket(date, date.length, inet,6000);
ds.send(dp);
}
// ds.close();
}
}
/*
* 實現UDP接收端
* 永不停歇的接收端
*/
public class UDPReceive {
public static void main(String[] args)throws IOException {
//創建數據包傳輸對象DatagramSocket 綁定埠號
DatagramSocket ds = new DatagramSocket(6000);
//創建位元組數組
byte[] data = new byte[1024];
//創建數據包對象,傳遞位元組數組
while(true){
DatagramPacket dp = new DatagramPacket(data, data.length);
//調用ds對象的方法receive傳遞數據包
ds.receive(dp);
//獲取發送端的IP地址對象
String ip=dp.getAddress().getHostAddress();
//獲取發送的埠號
int port = dp.getPort();
//獲取接收到的位元組個數
int length = dp.getLength();
System.out.println(new String(data,0,length)+"..."+ip+":"+port);
}
//ds.close();
}
}
12TCP的客戶端和伺服器
*A:TCP的客戶端和伺服器
TCP通信同UDP通信一樣,都能實現兩台電腦之間的通信,通信的兩端都需要創建socket對象。
區別在於,UDP中只有發送端和接收端,不區分客戶端與伺服器端,電腦之間可以任意地發送數據。
而TCP通信是嚴格區分客戶端與伺服器端的,在通信時,必須先由客戶端去連接伺服器端才能實現通信,
伺服器端不可以主動連接客戶端,並且伺服器端程式需要事先啟動,等待客戶端的連接。
在JDK中提供了兩個類用於實現TCP程式,一個是ServerSocket類,用於表示伺服器端,一個是Socket類,用於表示客戶端。
通信時,首先創建代表伺服器端的ServerSocket對象,該對象相當於開啟一個服務,並等待客戶端的連接,然後創建代表客戶端的Socket對象向伺服器端發出連接請求,伺服器端響應請求,兩者建立連接開始通信。
13TCP的客戶端程式
*A:TCP的客戶端程式
/*
* 實現TCP客戶端,連接到伺服器
* 和伺服器實現數據交換
* 實現TCP客戶端程式的類 java.net.Socket
*
* 構造方法:
* Socket(String host, int port) 傳遞伺服器IP和埠號
* 註意:構造方法只要運行,就會和伺服器進行連接,連接失敗,拋出異常
*
* OutputStream getOutputStream() 返回套接字的輸出流
* 作用: 將數據輸出,輸出到伺服器
*
* InputStream getInputStream() 返回套接字的輸入流
* 作用: 從伺服器端讀取數據
*
* 客戶端伺服器數據交換,必須使用套接字對象Socket中的獲取的IO流,自己new流,不行
*/
public class TCPClient {
public static void main(String[] args)throws IOException {
//創建Socket對象,連接伺服器
Socket socket = new Socket("127.0.0.1", 8888);
//通過客戶端的套接字對象Socket方法,獲取位元組輸出流,將數據寫向伺服器
OutputStream out = socket.getOutputStream();
out.write("伺服器OK".getBytes());
socket.close();
}
}
14TCP的伺服器程式accept方法
A:TCP的伺服器程式accept方法
/*
* 實現TCP伺服器程式
* 表示伺服器程式的類 java.net.ServerSocket
* 構造方法:
* ServerSocket(int port) 傳遞埠號
*
* 很重要的事情: 必須要獲得客戶端的套接字對象Socket
* Socket accept()
*/
public class TCPServer {
public static void main(String[] args) throws IOException{
ServerSocket server = new ServerSocket(8888);
//調用伺服器套接字對象中的方法accept() 獲取客戶端套接字對象
Socket socket = server.accept();
//通過客戶端套接字對象,socket獲取位元組輸入流,讀取的是客戶端發送來的數據
InputStream in = socket.getInputStream();
byte[] data = new byte[1024];
int len = in.read(data);
System.out.println(new String(data,0,len));
socket.close();
server.close();
}
}
15TCP的伺服器程式讀取客戶端數據
A:TCP的伺服器程式讀取客戶端數據
/*
* 實現TCP客戶端,連接到伺服器
* 和伺服器實現數據交換
* 實現TCP客戶端程式的類 java.net.Socket
*
* 構造方法:
* Socket(String host, int port) 傳遞伺服器IP和埠號
* 註意:構造方法只要運行,就會和伺服器進行連接,連接失敗,拋出異常
*
* OutputStream getOutputStream() 返回套接字的輸出流
* 作用: 將數據輸出,輸出到伺服器
*
* InputStream getInputStream() 返回套接字的輸入流
* 作用: 從伺服器端讀取數據
*
* 客戶端伺服器數據交換,必須使用套接字對象Socket中的獲取的IO流,自己new流,不行
*/
public class TCPClient {
public static void main(String[] args)throws IOException {
//創建Socket對象,連接伺服器
Socket socket = new Socket("127.0.0.1", 8888);
//通過客戶端的套接字對象Socket方法,獲取位元組輸出流,將數據寫向伺服器
OutputStream out = socket.getOutputStream();
out.write("伺服器OK".getBytes());
socket.close();
}
}
/*
* 實現TCP伺服器程式
* 表示伺服器程式的類 java.net.ServerSocket
* 構造方法:
* ServerSocket(int port) 傳遞埠號
*
* 很重要的事情: 必須要獲得客戶端的套接字對象Socket
* Socket accept()
*/
public class TCPServer {
public static void main(String[] args) throws IOException{
ServerSocket server = new ServerSocket(8888);
//調用伺服器套接字對象中的方法accept() 獲取客戶端套接字對象
Socket socket = server.accept();
//通過客戶端套接字對象,socket獲取位元組輸入流,讀取的是客戶端發送來的數據
InputStream in = socket.getInputStream();
byte[] data = new byte[1024];
int len = in.read(data);
System.out.println(new String(data,0,len));
}
}
16TCP的伺服器和客戶端的數據交換
A:TCP的伺服器和客戶端的數據交換
/*
* 實現TCP客戶端,連接到伺服器
* 和伺服器實現數據交換
* 實現TCP客戶端程式的類 java.net.Socket
*
* 構造方法:
* Socket(String host, int port) 傳遞伺服器IP和埠號
* 註意:構造方法只要運行,就會和伺服器進行連接,連接失敗,拋出異常
*
* OutputStream getOutputStream() 返回套接字的輸出流
* 作用: 將數據輸出,輸出到伺服器
*
* InputStream getInputStream() 返回套接字的輸入流
* 作用: 從伺服器端讀取數據
*
* 客戶端伺服器數據交換,必須使用套接字對象Socket中的獲取的IO流,自己new流,不行
*/
public class TCPClient {
public static void main(String[] args)throws IOException {
//創建Socket對象,連接伺服器
Socket socket = new Socket("127.0.0.1", 8888);
//通過客戶端的套接字對象Socket方法,獲取位元組輸出流,將數據寫向伺服器
OutputStream out = socket.getOutputStream();
out.write("伺服器OK".getBytes());
//讀取伺服器發回的數據,使用socket套接字對象中的位元組輸入流
InputStream in = socket.getInputStream();
byte[] data = new byte[1024];
int len = in.read(data);
System.out.println(new String(data,0,len));
socket.close();
}
}
/*
* 實現TCP伺服器程式
* 表示伺服器程式的類 java.net.ServerSocket
* 構造方法:
* ServerSocket(int port) 傳遞埠號
*
* 很重要的事情: 必須要獲得客戶端的套接字對象Socket
* Socket accept()
*/
public class TCPServer {
public static void main(String[] args) throws IOException{
ServerSocket server = new ServerSocket(8888);
//調用伺服器套接字對象中的方法accept() 獲取客戶端套接字對象
Socket socket = server.accept();
//通過客戶端套接字對象,socket獲取位元組輸入流,讀取的是客戶端發送來的數據
InputStream in = socket.getInputStream();
byte[] data = new byte[1024];
int len = in.read(data);
System.out.println(new String(data,0,len));
//伺服器向客戶端回數據,位元組輸出流,通過客戶端套接字對象獲取位元組輸出流
OutputStream out = socket.getOutputStream();
out.write("收到,謝謝".getBytes());
socket.close();
server.close();
}
}
17TCP的中的流對象
18TCP圖片上傳案例分析
19TCP上傳客戶端
*A TCP上傳客戶端
/*
* 實現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();
}
}
20TCP上傳伺服器
A:TCP上傳伺服器
/*
* TCP圖片上傳伺服器
* 1. ServerSocket套接字對象,監聽埠8000
* 2. 方法accept()獲取客戶端的連接對象
* 3. 客戶端連接對象獲取位元組輸入流,讀取客戶端發送圖片
* 4. 創建File對象,綁定上傳文件夾
* 判斷文件夾存在, 不存,在創建文件夾
* 5. 創建位元組輸出流,數據目的File對象所在文件夾
* 6. 位元組流讀取圖片,位元組流將圖片寫入到目的文件夾中
* 7. 將上傳成功會寫客戶端
* 8. 關閉資源
*
*/
public class TCPServer {
public static void main(String[] args) throws IOException{
ServerSocket server = new ServerSocket(8000);
Socket socket = server.accept();
//通過客戶端連接對象,獲取位元組輸入流,讀取客戶端圖片
InputStream in = socket.getInputStream();
//將目的文件夾封裝到File對象
File upload = new File("d:\\upload");
if(!upload.exists())
upload.mkdirs();
//創建位元組輸出流,將圖片寫入到目的文件夾中
FileOutputStream fos = new FileOutputStream(upload+"t.jpg");
//讀寫位元組數組
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();
server.close();
}
}
21TCP圖片上傳問題解決
/*
* 實現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();
}
}
TCP上傳文件名
*A:TCP上傳文件名
/*
* TCP圖片上傳伺服器
* 1. ServerSocket套接字對象,監聽埠8000
* 2. 方法accept()獲取客戶端的連接對象
* 3. 客戶端連接對象獲取位元組輸入流,讀取客戶端發送圖片
* 4. 創建File對象,綁定上傳文件夾
* 判斷文件夾存在, 不存,在創建文件夾
* 5. 創建位元組輸出流,數據目的File對象所在文件夾
* 6. 位元組流讀取圖片,位元組流將圖片寫入到目的文件夾中
* 7. 將上傳成功會寫客戶端
* 8. 關閉資源
*
*/
public class TCPServer {
public static void main(String[] args) throws IOException{
ServerSocket server = new ServerSocket(8000);
Socket socket = server.accept();
//通過客戶端連接對象,獲取位元組輸入流,讀取客戶端圖片
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();
server.close();
}
}
多線程上傳案例
*A:多線程上傳案例
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();
}
}
}
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) {
}
}
}