31_網絡編程(Socket套接字編程)_講義

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

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

      }
    }

  }
相關文章
相關標籤/搜索