Java-網絡編程基礎

網絡基礎知識

網絡編程的目的:直接或間接得通過網絡協議與其他計算機進行通信。
目前較爲流行的網絡編程模型是客戶端/服務器(C/S)結構
即通信雙方一方作爲服務器等待客戶提出請求並予以相應。客戶則在需要服務時向服務器提出申請。
服務器始終運行,監聽網絡端口,一旦有客戶請求,就會啓動一個服務線程來響應該客戶,同時自己繼續監聽服務窗口,使後來的客戶也能及時得到服務。

兩臺主機 進行通信的必備條件 IP地址、協議、端口。

  • IP地址

    IP網絡中每臺主機必須有一個唯一的IP地址,IP地址是一個邏輯地址。
    IP 地址具有全球唯一性。
    32位,四個字節,常用點分十進制的格式表示。

  • 協議

    爲進行網絡中的數據交換(通信)而建立的規則、標準或約定。(=語義+語法+規則)。

    • TCP/IP協議

      TCP/IP是目前世界上應用最爲廣泛的協議,是以TCP和IP爲基礎的不同層次上多個協議的集合,也稱:TCP/IP協議族 或 TCP/IP協議族。
      TCP:Transmission Control Protoclol 傳輸控制協議
      IP:Internet Protocol 互聯網協議
      TCP/IP協議是一個開放的網絡協議簇,它的名字主要取自最重要的網絡層IP協議和傳輸層TCP協議。TCP/IP協議定義了電子設備如何連入因特網,以及數據如何在它們之間傳輸的標準。TCP/IP參考模型採用4層的層級結構,每一層都呼叫它的下一層所提供的協議來完成自己的需求,這4個層次分別是:網絡接口層、互聯網層(IP層)、傳輸層(TCP層)、應用層。

    • UDP協議

      UDP,用戶數據報協議,英文全稱是User Datagram Protocol,它是TCP/IP協議簇中無連接的運輸層協議。
      UDP協議十分簡單,它由兩部分組成:首部和數據。其中,首部僅有8個字節,包括源端口和目的端口,長度(UDP用於數據報的長度)、校驗和。

  • 端口

    1、在互聯網上傳輸的數據都包含有用來識別目的地的IP地址和端口號。
    2、IP地址用來標識網絡上的計算機,而端口號用來指明該計算機上的應用程序。
    3、端口是一種抽象的軟件結構(包括一些數據結構和I/O緩衝區)
    4、應用程序通過系統調用與某端口建立連接(binding)後,傳輸層傳給該端口的數據都被相應的進程所接收,相應進程發給傳輸層的數據都通過該端口輸出
    5、端口用一個整數型標識符來表示,即端口號。
    6、端口號跟協議相關,TCP/IP傳輸層的兩個協議TCP和UDP是完全獨立的兩個軟件模塊,因此各自的端口號也相互獨立,端口通常稱爲協議端口(protocol port),簡稱端口。
    7、端口號範圍爲0~65535 ,其中0~1023爲系統保留
    8、IP地址和端口號組成了所謂的Socket,Socket是網絡上運行的程序之間雙向通信鏈路的終結點,是TCP和UDP的基礎
    9、http:80 ftp:21 telnet:23

  • java中的網絡支持

    針對網絡通信的不同層次,Java提供的網絡功能有四大類:
    1、InetAddress:用於標識網絡上的硬件資源
    2、URl:統一定位符 通過URL可以直接讀取或寫入網絡上的數據。
    3、Sockets:使用TCP協議實現網絡通信的Socket相關的類
    4、Datagram :使用UDP協議,將數據保存在數據報中,通過網絡進行通信

    • InetAddress類

      InetrAddress 類用於標識網絡上的硬件資源,表示互聯網協議(IP)地址,該類沒有構造方法,可以通過靜態方法獲取一個實例。

       
      // 獲取本機的InetAddress實例
      InetAddress address = InetAddress.getLocalHost();
      System.out.println(“計算名:” + address.getHostName());
      System.out.println(“IP地址:” + address.getHostAddress());
      byte[] bytes = address.getAddress();// 獲取字節數組形式的IP地址
      System.out.println(“字節數組形式的IP:” + Arrays.toString(bytes));
      System.out.println(address);// 直接輸出InetAddress對象 將輸出計算機名和IP地址

      // 根據機器名獲取InetAddress實例
      InetAddress address2=InetAddress.getByName(“laurenyang”);
      //根據IP地址獲取
      InetAddress address2 = InetAddress.getByName(“1.1.1.10”);
      System.out.println(“計算名:” + address2.getHostName());
      System.out.println(“IP地址:” + address2.getHostAddress());

    • URL

      1、URL統一資源定位符,表示Internet某一資源的地址
      2、URL由兩部分組成:協議名稱和資源名稱,中間用冒號隔開。
      3、在Java.nat包中,提供了URL來來表示URL
      使用URL讀取網頁內容
      1、通過URL對象的openStream()方法可以得到指定資源的輸入流。
      2、通過輸入流可以讀取、 訪問網絡上的數據

       
      try {
      //創建一個URL實例
      URL url = new URL("http://www.baidu.com");
      //通過URL的openStream方法獲取URL對象所表示的資源的字節輸入流
      InputStream is = url.openStream();
      //將字節輸入流轉換爲字符輸入流
      InputStreamReader isr = new InputStreamReader(is, "utf-8");
      //爲字符輸入流添加緩衝
      BufferedReader br = new BufferedReader(isr);
      String data = br.readLine();//讀取數據
      while (data != null) {//循環讀取數據
      System.out.println(data);//輸出數據
      data = br.readLine();
      }
      br.close();
      isr.close();
      is.close();
      } catch (MalformedURLException e) {
      e.printStackTrace();
      } catch (IOException e) {
      e.printStackTrace();
      }

  • Socket TCP通信

    TCP協議是面向連接、可靠、有序的,以字節流的方式發送數據
    基於TCP協議實現網絡通信的類:
    1) 客戶端的Socket類
    2) 服務器端的ServerSocket類

    • Socket通信實現步驟

      1、創建ServerSocket和Socket
      2、打開連接到Socket的輸入/輸出流
      3、按照協議對Socket進行讀/寫操作
      4、關閉輸入輸出流、關閉Socket

    • 服務器端:

      1、創建ServerSocket對象,綁定監聽端口
      2、通過accept()方法監聽客戶端請求
      3、連接建立後,通過輸入流讀取客戶端發送的請求信息
      4、通過輸出流向客戶端發送響應信息
      5、關閉相關資源

       
      try {
      //創建一個服務器端Socket,即SeverSocket,指定綁定的端口,並監聽此藉口
      ServerSocket serverSocket=new ServerSocket(8888);
      System.out.println(“服務器端 等待連接**“);
      //調用accept()方法開始監聽,等待客戶端的連接
      Socket socket=serverSocket.accept();
      //獲取輸入流,並讀取客戶端信息
      java.io.InputStream is=socket.getInputStream();//字節輸入流
      InputStreamReader isr=new InputStreamReader(is);//將字節流轉換爲字符流
      BufferedReader br=new BufferedReader(isr);//爲輸入流添加緩衝
      String info=null;
      while((info=br.readLine())!=null){//循環讀取客戶端信息
      System.out.println(“收到客戶端消息: “+info);
      }

      //獲取輸出流,響應客戶端的請求
      OutputStream os=socket.getOutputStream();
      PrintWriter pw=new PrintWriter(os);
      pw.write(“我是服務器端”);
      pw.flush();

      socket.shutdownInput();//關閉輸入流
      pw.close();
      os.close();
      br.close();
      isr.close();
      is.close();
      socket.close();
      serverSocket.close();
      } catch (IOException e) {
      e.printStackTrace();
      }

    • 客戶端

      1、創建Socket對象,指明需要連接的服務器的地址和端口號
      2、連接建立後,通過輸出流向服務器端發送請求信息
      3、通過輸入流獲取服務器響應的信息
      4、關閉相關資源

       
      try {
      // 創建客戶端Socket,指定服務器地址和端口
      Socket socket = new Socket(“localhost”, 8888);
      // 獲取輸出流,向服務器發送信息
      OutputStream os = socket.getOutputStream();// 字節輸出流
      PrintWriter pw = new PrintWriter(os);// 字節流轉化爲字符流
      pw.write(“我是客戶端”);
      pw.flush();
      socket.shutdownOutput();
      // 獲取輸入流,並讀取服務器端的響應
      java.io.InputStream is = socket.getInputStream();
      BufferedReader br = new BufferedReader(new InputStreamReader(is));
      String info = null;
      while ((info = br.readLine()) != null) {// 循環讀取客戶端信息
      System.out.println(“收到服務器端消息: “+info);
      }

        pw.close();
        br.close();
        is.close();
        os.close();
        socket.close();
      

      } catch (UnknownHostException e) {
      e.printStackTrace();
      } catch (IOException e) {
      e.printStackTrace();
      }

  • Socket UDP通信..

    1、UDP(用戶數據報協議)是無連接,不可靠的、無序的。
    2、UDP協議以數據報作爲數據傳輸的載體
    3、進行數據傳輸時,首先需要將要傳輸的數據定義成數據報(Datagram),在數據報中指明數據所要到達的Socket(主機地址和端口號),然後再將數據報發送出去。
    相關操作類
    1) DatagramPacket:表示數據報包
    2) DatagramSocket :進行端到端通信的類

    • 服務器端實現步驟

      1、創建DatagramSocket ,指定端口號
      2、創建DatagramPacket
      3、接受客戶端發送的數據信息
      4、讀取數據

       
      import java.io.IOException;
      import java.net.DatagramPacket;
      import java.net.DatagramSocket;
      import java.net.InetAddress;

      public class UDPServer {
      public static void main(String[] args) throws IOException {

          //接收客戶端發送的數據
          // 1.創建服務器端DatagramSocket,指定端口
          DatagramSocket socket = new DatagramSocket(8800);
          // 2.創建數據報,用於接收客戶端發送的數據
          byte[] data = new byte[1024];// 創建字節數組,指定接收的數據包的大小
          DatagramPacket packet = new DatagramPacket(data, data.length);
          // 3.接收客戶端發送的數據
          System.out.println("****服務器端已經啓動,等待客戶端發送數據");
          socket.receive(packet);// 此方法在接收到數據報之前會一直阻塞
          // 4.讀取數據
          String info = new String(data, 0, packet.getLength());
          System.out.println("我是服務器,客戶端說:" + info);
      
         /*
          * 向客戶端響應數據
          */
          // 1.定義客戶端的地址、端口號、數據
          InetAddress address = packet.getAddress();
          int port = packet.getPort();
          byte[] data2 = "歡迎您!".getBytes();
          // 2.創建數據報,包含響應的數據信息
          DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
         // 3.響應客戶端
           socket.send(packet2);
         // 4.關閉資源
          socket.close();
          }
      }
      

    • 客戶端實現步驟

      1、定義發送信息
      2、創建DatagramPacket,包含將要發送的數據
      3、創建DatagramSocket
      4、發送數據

       
      import java.io.IOException;
      import java.net.DatagramPacket;
      import java.net.DatagramSocket;
      import java.net.InetAddress;
      import java.net.SocketException;
      import java.net.UnknownHostException;

      public class UDPClient {
      public static void main(String[] args) throws IOException {

          //向服務器端發送數據
          //1.定義服務器的地址、端口號、數據
          InetAddress address=InetAddress.getByName("localhost");
          int port=8800;
          byte[] data="用戶名:admin;密碼:123".getBytes();
          //2.創建數據報,包含發送的數據信息
          DatagramPacket packet=new DatagramPacket(data, data.length, address, port);
         //3.創建DatagramSocket對象
         DatagramSocket socket=new DatagramSocket();
         //4.向服務器端發送數據報
         socket.send(packet);
      
         /*
          * 接收服務器端響應的數據
          */
         //1.創建數據報,用於接收服務器端響應的數據
         byte[] data2=new byte[1024];
         DatagramPacket packet2=new DatagramPacket(data2, data2.length);
         //2.接收服務器響應的數據
         socket.receive(packet2);
        //3.讀取數據
        String reply=new String(data2, 0, packet2.getLength());
        System.out.println("我是客戶端,服務器說:"+reply);
        //4.關閉資源
        socket.close();
         }
      }
      

一個小菜鳥的整理,如果有什麼不足,歡迎評論 ^_^
整理自:
鏈接http://www.imooc.com/learn/161

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章