Socket應用

一. Java網絡相關API的應用

1. InetAddress類的應用

InetAddress類用於標識網絡上的硬件資源,主要用來表示互聯網協議(IP)地址的相關信息。
因爲InetAddress類沒有構造方法,所以不能直接new一個新的實例。我們可以通過InetAddress類中的一些靜態方法來獲取到一個實例。

    InetAddress address = InetAddress.getLocalHost();  //獲取本機信息,返回一個InetAddress類的實例。
    InetAddress address = InetAddress.getByName();  //根據機器名獲取信息,返回一個InetAddress類的實例。

獲取到實例之後就可以利用InetAddress中的方法去獲取需要的信息。

    address.getHostName();  //獲取主機名
    address.getHostAddress();  //獲取IP地址

2. URL類的應用

URL(Uniform Resource Locator) 統一資源定位符,實際上就是表示Internet上的某一個資源的地址,即俗稱的網址。
URL由兩部分組成:
一部分是協議名稱,另一部分叫資源名稱。它們之間用冒號( : )隔開。
要使用URL類,第一步就是先創建一個URL類的實例。

    URL url = new URL("http://blog.csdn.net/czb1n");  //根據一個資源字符串來創建一個URL類的實例。
    URL url2 = new URL(url,"/article");  //通過已有的URL實例來創建一個新的URL類的實例。也可以通過使用問號(?)來傳參數,用井號(#)來指定錨點。

創建好實例之後就可以通過URL類中的方法來獲取需要的信息。

     url.getProtocol();  //獲取協議信息
     url.getHost();  //獲取主機信息
     url.getPort();  //獲取端口號信息。這裏需要注意的是如果url沒有指定端口號的情況下,則使用默認的端口號,但此時getPort()方法的返回值爲-1。
     url.getPath();  //獲取文件路徑
     url.getRef();  //獲取文件的相對路徑
     url.getFile(); //獲取文件名
     url.getQuery();  //獲取查詢字符串

還可以用URL類來讀取網頁上的內容,通過URL對象中的openStream()方法可以得到一個指定資源的字節輸入流(InputStream),通過輸入流可以讀取和訪問網絡上的數據。

    InputStream is = url.openStream();  //獲取指定資源的字節輸入流
    InputStreamReader isr = new InputStreamReader(is, "utf-8");  //把字節輸入流轉換爲字符輸入流並指定字符集
    BufferedReader br = new BufferedReader(isr); //爲字符輸入流添加緩衝

利用一個循環每次讀取一行來讀取網頁的數據。

    String data = null;
    while((data = br.readLine()) != null){
        System.out.println(data);
        data = br.readLine();
    }

讀取完畢之後需要把相應的資源和輸入流關閉。

    br.close();
    isr.close();
    is.close();

二. 通過 Socket 實現 TCP 編程

TCP(Transmission Control Protocol)傳輸控制協議是面向連接、可靠的、有序的、以字節流的方式發送數據。基於TCP協議實現網絡通信的類有兩個:
客服端的Socket類,服務器端的ServerSocket類。

Socket的通信模型:
Socket的通信模型

使用Socket通信實現的步驟:

1. 服務器端:

    ServerSocket serverSocket = new ServerSocket(8888);  //創建ServerSocket,指定綁定並監聽端口。
    Socket socket = serverSocket.accept();
    //調用accept()方法開始監聽端口,一旦調用這個方法即進入阻塞狀態,等待客戶端的連接返回一個Socket的實例。
    //客戶端連接後,用Socket對象中的getInputStream()方法獲取到一個字節輸入流並讀取客戶端信息。
    InputStream is = socket.getInputStream();  //獲取字節輸入流
    InputStreamReader isr = new InputStreamReader(is)  //將字節輸入流轉換爲字符輸入流
    BufferedReader br = new BufferedReader(isr)  //爲字符輸入流添加緩衝

利用一個循環每次讀取一行來讀取客戶端發送過來的信息。

    String data = null;
    while((data = br.readLine()) != null){
        System.out.println(data);
        data = br.readLine();
    }

讀取完畢之後需要把相應的資源和輸入流關閉。

    socket.shutdownInput();
    br.close();
    isr.close();
    is.close();
    socket.close();
    serverSocket.close();

2. 客戶端:

    Socket socket = new Socket("localhost", 8888);  //指定服務器地址和端口號,創建一個客戶端Socket,用來給服務器端發送信息。
    OutputStream os = socket.getOutputStream();  //獲取一個字節輸出流,用來給服務器端發送信息。
    PrintWriter pw = new PrintWriter(os);  //將字節輸出流包裝爲打印流
    pw.write("my name is czb1n!");  //發送信息
    pw.flush();  //刷新緩存

讀取完畢之後需要把相應的資源和輸入流關閉。

    socket.shutdownOutput();
    pw.close();
    os.close();
    socket.close();

三. 通過 Socket 實現 UDP 編程

UDP(User Datagram Protocol)用戶數據報協議是無連接、不可靠的、無序的、以數據報(Datagram)作爲數據傳輸的載體。和TCP協議一樣,基於UDP協議實現網絡通信的類有兩個:
數據報包DatagramPacket類,進行端到端通信的DatagramSocket類。

使用Socket通信實現的步驟:

1. 服務器端:

    DatagramSocket socket = new DatagramSocket(8888);  //創建服務器端DatagramSocket並指定端口
    byte[] data = new byte[1024];  //創建一個指定大小的字節數組用於存儲數據
    DatagramPacket packet = new DatagramPacket(data, data.length);  //創建數據報包,用於接收客戶端發送的數據
    socket.receive(packet);  //接收客戶端發送的數據,和accept()方法一樣,一旦調用這個方法在接收到數據報之前會一直進入阻塞狀態。
    String info = new String(data, 0, packet.getLength());  //讀取數據,把字節數組接收到的數據轉換爲String

    //packet.getAddress();  獲取客戶端的地址
    //packet.getPort();  獲取客戶端的端口號

2. 客戶端:

    InetAddress address = InetAddress.getByName("localhost");  //根據主機名獲得服務器的信息
    int port = 8888;  //指定與服務器相同的端口號
    byte[] data = "my name is czb1n!".getBytes();  //把要發送的信息存儲在字節數組
    DatagramPacket packet = new DatagramPacket(data, data.length, address, port);  //創建一個包含發送的數據信息的數據報
    DatagramSocket socket = new DatagramSocket();  //創建一個DatagramSocket對象實例來發送信息
    socket.send(packet);  //發送數據報

以上TCP協議方式和UDP協議方式都僅實現了一個服務器端對一個客戶端之間的通信,可以應用多線程來實現服務器端和多個客戶端之間的通信。

Keep Going…

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