一、網絡三要素及傳輸協議 二、實現UDP協議的發送端和接收端 三、實現TCP協議的客戶端和服務器 四、TCP上傳文件案例

01網絡模型

*A:網絡模型java

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協議dom

TCP協議是面向鏈接的通訊協議,即在傳輸數據前先在發送端和接收端創建邏輯鏈接,而後再傳輸數據,它提供了兩臺計算機之間可靠無差錯的數據傳輸。
在TCP鏈接中必需要明確客戶端與服務器端,
  由客戶端向服務端發出鏈接請求,每次鏈接的建立都須要通過「三次握手」。
  第一次握手,客戶端向服務器端發出鏈接請求,等待服務器確認
  第二次握手,服務器端向客戶端回送一個響應,通知客戶端收到了鏈接請求
  第三次握手,客戶端再次向服務器端發送確認信息,確認鏈接

========================================第二節課=========================================socket

07數據包和發送對象介紹

*A:數據包和發送對象介紹:this

DatagramPacket數據包的做用就如同是「集裝箱」,
   能夠將發送端或者接收端的數據封裝起來。然而運輸貨物只有「集裝箱」是不夠的,還須要有碼頭。
   在程序中須要實現通訊只有DatagramPacket數據包也一樣不行,爲此JDK中提供的一個DatagramSocket類。
   DatagramSocket類的做用就相似於碼頭,使用這個類的實例對象就能夠發送和接收DatagramPacket數據包
DatagramPacket:封裝數據
DatagramSocket:發送DatagramPacket

08UDP發送端

*A:UDP發送端.net

/*
    *  實現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的中的流對象

*A:TCP的中的流對象
    參見圖解TCP中的流對象.jpg

======================================第四節課=================================================

18TCP圖片上傳案例分析

*A:圖片上傳案例分析
     參見圖解TCP上傳圖片案例.jpg

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套接字鏈接服務器

    1. 經過Socket獲取字節輸出流,寫圖片

    1. 使用本身的流對象,讀取圖片數據源

  • FileInputStream

    1. 讀取圖片,使用字節輸出流,將圖片寫到服務器

  • 採用字節數組進行緩衝

    1. 經過Socket套接字獲取字節輸入流

  • 讀取服務器發回來的上傳成功

    1. 關閉資源
      */

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) {

  }
}

}

相關文章
相關標籤/搜索