day30_網絡編程初識

網絡編程入門

計算機網絡

是指將地理位置不同的具有獨立功能的多臺計算機及其外部設備,通過通信線路連接起來,在網絡操作系 統,網絡管理軟件及網絡通信協議的管理和協調下,實現資源共享和信息傳遞的計算機系統

網絡編程

在網絡通信協議下,實現網絡互連的不同計算機上運行的程序間可以進行數據交換

網絡編程三要素

IP地址

  • 要想讓網絡中的計算機能夠互相通信,必須爲每臺計算機指定一個標識號,通過這個標識號來指定要接收數 據的計算機和識別發送的計算機,而IP地址就是這個標識號。也就是設備的標識

IP地址詳解

  • IP地址:指互聯網協議地址(Internet Protocol Address,俗稱IPIP地址用來給一個網絡中的計算機設 備做唯一的編號。假如我們把“個人電腦比作一臺電話的話,那麼“IP地址就相當於電話號碼

IP地址分類

  • IPv4是一個32位的二進制數,通常被分爲4個字節,表示成 a.b.c.d 的形式,例如 192.168.65.100 。其 中abcd都是0~255之間的十進制整數,那麼最多可以表示42億個。
  • IPv6由於互聯網的蓬勃發展,IP地址的需求量愈來愈大,但是網絡地址資源有限,使得IP的分配越發緊張。 有資料顯示,全球IPv4地址在20112月分配完畢。 爲了擴大地址空間,擬通過IPv6重新定義地址空間,採用128位地址長度,每16個字節一組,分成8組十六進 制數,表示成 ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 ,號稱可以爲全世界的每一粒沙子編上一個網址,這樣就解決了網絡地址資源數量不夠的問題。

常用命令

  • 查看本機IP地址,在控制檯輸入:ipconfig
  • 檢查網絡是否連通,在控制檯輸入:ping 空格 IP地址  

特殊的IP地址

  • 本機IP地址: 127.0.0.1 localhost 

端口

  • 網絡的通信,本質上是兩個進程(應用程序)的通信。每臺計算機都有很多的進程,那麼在網絡通信時,如何區分 這些進程呢? 如果說IP地址可以唯一標識網絡中的設備,那麼端口號就可以唯一標識設備中的進程(應用程序)了。
  • 端口號:用兩個字節表示的整數,它的取值範圍是0~65535。其中,0~1023之間的端口號用於一些知名的網絡服務和應用,普通的應用程序需要使用1024以上的端口號。如果端口號被另外一個服務或應用所佔用,會 導致當前程序啓動失敗。

協議

  • 通過計算機網絡可以使多臺計算機實現連接,位於同一個網絡中的計算機在進行連接和通信時需要遵守一定 的規則,這就好比在道路中行駛的汽車一定要遵守交通規則一樣。在計算機網絡中,這些連接和通信的規則 被稱爲網絡通信協議,它對數據的傳輸格式、傳輸速率、傳輸步驟等做了統一規定,通信雙方必須同時遵守 才能完成數據交換。常見的協議有UDP協議和TCP協議

UDP協議詳解

  • 用戶數據報協議(User Datagram Protocol)
  • UDP是無連接通信協議,即在數據傳輸時,數據的發送端和接收端不建立邏輯連接。簡單來說,當一臺 計算機向另外一臺計算機發送數據時,發送端不會確認接收端是否存在,就會發出數據,同樣接收端在 收到數據時,也不會向發送端反饋是否收到數據。
  • 由於使用UDP協議消耗資源小,通信效率高,所以通常都會用於音頻、視頻和普通數據的傳輸
  • 例如視頻會議通常採用UDP協議,因爲這種情況即使偶爾丟失一兩個數據包,也不會對接收結果產生太 大影響。但是在使用UDP協議傳送數據時,由於UDP的面向無連接性,不能保證數據的完整性,因此在 傳輸重要數據時不建議使用UDP協議

TCP協議詳解

TCP協議是面向連接的通信協議,即傳輸數據之前,在發送端和接收端建立邏輯連接,然後再傳輸數據,它提供了兩臺計算機之間可靠無差錯的數據傳輸。在TCP連接中必須要明確客戶端與服務器端,由 客戶端向服務端發出連接請求,每次連接的創建都需要經過“三次握手”。三次握手:TCP協議中,在發送數據的準備階段,客戶端與服務器之間的三次交互,以保證連接的可靠

  • 第一次握手,客戶端向服務器端發出連接請求,等待服務器確認
  • 第二次握手,服務器端向客戶端回送一個響應,通知客戶端收到了連接請求
  • 第三次握手,客戶端再次向服務器端發送確認信息,確認連接
完成三次握手,連接建立後,客戶端和服務器就可以開始進行數據傳輸了。由於這種面向連接的特性, TCP協議可以保證傳輸數據的安全,所以應用十分廣泛。例如上傳文件、下載文件、瀏覽網頁等

InetAdress

此類表示Internet協議(IP)地址 InetAddress類沒有提供公共的構造器,而是提供瞭如下幾個靜態方法來獲取 InetAddress實例

  • public static InetAddress getLocalHost()
  • public static InetAddress getByName(String host)

InetAddress提供瞭如下幾個常用的方法

  • public String getHostAddress()返回 IP 地址字符串(以文本表現形式)。
  • public String getHostName()獲取此 IP 地址的主機名
  • public boolean isReachable(int timeout)測試是否可以達到該地址

代碼舉例

package ThreadDemo;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress address = InetAddress.getByName("192.168.1.66");
        //public String getHostName():獲取此IP地址的主機名
        String name = address.getHostName();
        //public String getHostAddress():返回文本顯示中的IP地址字符串
        String ip = address.getHostAddress();
        System.out.println("主機名:" + name);
        System.out.println("IP地址:" + ip);
    }
}

Socket

  • 利用套接字(Socket)開發網絡應用程序早已被廣泛的採用,以至於成爲事實 上的標準。
  • 網絡上具有唯一標識的IP地址和端口號組合在一起才能構成唯一能識別的標 識符套接字。
  • 通信的兩端都要有Socket,是兩臺機器間通信的端點。
  • 網絡通信其實就是Socket間的通信。
  • Socket允許程序把網絡連接當成一個流,數據在兩個Socket間通過IO傳輸。
  • 一般主動發起通信的應用程序屬客戶端,等待通信請求的爲服務端。

Socket分類:

  • 流套接字(stream socket):使用TCP提供可依賴的字節流服務
  • 數據報套接字(datagram socket):使用UDP提供“盡力而爲”的數據報服務

Socket類的常用構造器:

  • public Socket(InetAddress address,int port)創建一個流套接字並將其連接到指定 IP 地址的指定端口號。
  • public Socket(String host,int port)創建一個流套接字並將其連接到指定主機上的指定端口號。

Socket類的常用方法:

  • public InputStream getInputStream()返回此套接字的輸入流。可以用於接收網絡消息
  • public OutputStream getOutputStream()返回此套接字的輸出流。可以用於發送網絡消息
  • public InetAddress getInetAddress()此套接字連接到的遠程 IP 地址;如果套接字是未連接的,則返回 null
  • public InetAddress getLocalAddress()獲取套接字綁定的本地地址。 即本端的IP地址
  • public int getPort()此套接字連接到的遠程端口號;如果尚未連接套接字,則返回 0
  • public int getLocalPort()返回此套接字綁定到的本地端口。 如果尚未綁定套接字,則返回 -1。即本端的 端口號。
  • public void close()關閉此套接字。套接字被關閉後,便不可在以後的網絡連接中使用(即無法重新連接 或重新綁定)。需要創建新的套接字對象。 關閉此套接字也將會關閉該套接字的 InputStream 和 OutputStream。
  • public void shutdownInput()如果在套接字上調用 shutdownInput() 後從套接字輸入流讀取內容,則流將 返回 EOF(文件結束符)。 即不能在從此套接字的輸入流中接收任何數據。
  • public void shutdownOutput()禁用此套接字的輸出流。對於 TCP 套接字,任何以前寫入的數據都將被髮送,並且後跟 TCP 的正常連接終止序列。 如果在套接字上調用 shutdownOutput() 後寫入套接字輸出流, 則該流將拋出 IOException。 即不能通過此套接字的輸出流發送任何數據。

UDP網絡通信

  • DatagramSocket DatagramPacket 實現了基於 UDP 協議網絡程序。
  • UDP數據報通過數據報套接字 DatagramSocket 發送和接收,系統不保證 UDP數據報一定能夠安全送到目的地,也不能確定什麼時候可以抵達。
  • DatagramPacket 對象封裝了UDP數據報,在數據報中包含了發送端的IP 地址和端口號以及接收端的IP地址和端口號。
  • UDP協議中每個數據報都給出了完整的地址信息,因此無須建立發送方和 接收方的連接。如同發快遞包裹一樣。

DatagramPacket類的常用方法

  • public DatagramPacket(byte[] buf,int length)構造 DatagramPacket,用來接收長 度爲 length 的數據包。 length 參數必須小於等於 buf.length
  • public DatagramPacket(byte[] buf,int length,InetAddress address,int port)構造數 據報包,用來將長度爲 length 的包發送到指定主機上的指定端口號。length 參數必須小於等於 buf.length
  • public InetAddress getAddress()返回某臺機器的 IP 地址,此數據報將要發往該 機器或者是從該機器接收到的。
  • public int getPort()返回某臺遠程主機的端口號,此數據報將要發往該主機或 者是從該主機接收到的。
  • public byte[] getData()返回數據緩衝區。接收到的或將要發送的數據從緩衝區 中的偏移量 offset 處開始,持續 length 長度。
  • public int getLength()返回將要發送或接收到的數據的長度。

流 程:

  1. DatagramSocketDatagramPacket
  2. 建立發送端,接收端
  3. 建立數據包
  4. 調用Socket的發送、接收方法
  5. 關閉Socket

發送端與接收端是兩個獨立的運行程序

接收端,要指定監聽的端口。



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

/*
    UDP接收數據的步驟
        1:創建接收端的Socket對象(DatagramSocket)
        2:創建一個數據包,用於接收數據
        3:調用DatagramSocket對象的方法接收數據
        4:解析數據包,並把數據在控制檯顯示
        5:關閉接收端
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //創建接收端的Socket對象(DatagramSocket)
        //DatagramSocket​(int port) 構造數據報套接字並將其綁定到本地主機上的指定端口
        DatagramSocket ds = new DatagramSocket(10086);

        //創建一個數據包,用於接收數據
        //DatagramPacket​(byte[] buf, int length) 構造一個 DatagramPacket用於接收長度爲 length數據包
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys,bys.length);

        //調用DatagramSocket對象的方法接收數據
        ds.receive(dp);

        //解析數據包,並把數據在控制檯顯示
        //byte[] getData() 返回數據緩衝區
//        byte[] datas = dp.getData();
        //int getLength​() 返回要發送的數據的長度或接收到的數據的長度
//        int len = dp.getLength();
//        String dataString = new String(datas,0,len);
//        System.out.println("數據是:" + dataString);
        System.out.println("數據是:" + new String(dp.getData(),0,dp.getLength()));

        //關閉接收端
        ds.close();
    }
}

發送端



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/*
    UDP發送數據:
        數據來自於鍵盤錄入,直到輸入的數據是886,發送數據結束
 */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        //創建發送端的Socket對象(DatagramSocket)
        DatagramSocket ds = new DatagramSocket();

        //自己封裝鍵盤錄入數據
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = br.readLine()) != null) {
            //輸入的數據是886,發送數據結束
            if ("886".equals(line)) {
                break;
            }

            //創建數據,並把數據打包
            byte[] bys = line.getBytes();
            DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("192.168.1.66"), 12345);

            //調用DatagramSocket對象的方法發送數據
            ds.send(dp);
        }

        //關閉發送端
        ds.close();
    }
}

 TCP網絡編程

客戶端Socket的工作過程包含以下四個基本的步驟
  • 創建 Socket根據指定服務端的 IP 地址或端口號構造 Socket 類對象。若服務器端 響應,則建立客戶端到服務器的通信線路。若連接失敗,會出現異常。
  • 打開連接到 Socket 的輸入/出流: 使用 getInputStream()方法獲得輸入流,使用 getOutputStream()方法獲得輸出流,進行數據傳輸
  • 按照一定的協議對 Socket 進行讀/寫操作:通過輸入流讀取服務器放入線路的信息 (但不能讀取自己放入線路的信息),通過輸出流將信息寫入線程。
  • 關閉 Socket斷開客戶端到服務器的連接,釋放線路

客戶端程序可以使用Socket類創建對象,創建的同時會自動向服務器方發起連 Socket的構造器是:

  • Socket(String host,int port)throws UnknownHostException,IOException:向服務器(域名是 host。端口號爲port)發起TCP連接,若成功,則創建Socket對象,否則拋出異常。
  • Socket(InetAddress address,int port)throws IOException根據InetAddress對象所表示的 IP地址以及端口號port發起連接。

客戶端建立socketAtClient對象的過程就是向服務器發出套接字連接請求


import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/*
    TCP發送數據的步驟
        1:創建客戶端的Socket對象(Socket)
        2:獲取輸出流,寫數據
        3:釋放資源
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //創建客戶端的Socket對象(Socket)
        //Socket​(InetAddress address, int port) 創建流套接字並將其連接到指定IP地址的指定端口號
//        Socket s = new Socket(InetAddress.getByName("192.168.1.66"),10000);
        //Socket​(String host, int port) 創建流套接字並將其連接到指定主機上的指定端口號
        Socket s = new Socket("192.168.1.66",10000);

        //獲取輸出流,寫數據
        //OutputStream getOutputStream​() 返回此套接字的輸出流
        OutputStream os = s.getOutputStream();
        os.write("hello,tcp,我來了".getBytes());

        //釋放資源
        s.close();
    }
}

服務器程序的工作過程包含以下四個基本的步驟:

  1. 調用 ServerSocket(int port) 創建一個服務器端套接字,並綁定到指定端口上。用於監聽客戶端的請求。
  2. 調用 accept()監聽連接請求,如果客戶端請求連接,則接受連接,返回通信套接字對象。
  3. 調用 該Socket類對象的 getOutputStream() getInputStream ()獲取輸出 流和輸入流,開始網絡數據的發送和接收。
  4. 關閉ServerSocketSocket對象:客戶端訪問結束,關閉通信套接字。

ServerSocket 對象負責等待客戶端請求建立套接字連接,類似郵局某個窗口 中的業務員。也就是說,服務器必須事先建立一個等待客戶請求建立套接字 連接的ServerSocket對象。

所謂“接收”客戶的套接字請求,就是accept()方法會返回一個 Socket 對象

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
    TCP接收數據的步驟
        1:創建服務器端的Socket對象(ServerSocket)
        2:獲取輸入流,讀數據,並把數據顯示在控制檯
        3:釋放資源
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        //創建服務器端的Socket對象(ServerSocket)
        //ServerSocket​(int port) 創建綁定到指定端口的服務器套接字
        ServerSocket ss = new ServerSocket(10000);

        //Socket accept​() 偵聽要連接到此套接字並接受它
        Socket s = ss.accept();

        //獲取輸入流,讀數據,並把數據顯示在控制檯
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys,0,len);
        System.out.println("數據是:" + data);

        //釋放資源
        s.close();
        ss.close();
    }
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章