天天看點

Java入門 - 進階教程 - 05.網絡程式設計網絡程式設計

原文位址: http://www.work100.net/training/java-networking.html 更多教程: 光束雲 - 免費課程

網絡程式設計

請參照如上

章節導航

進行閱讀

1.概述

網絡程式設計是指編寫運作在多個裝置(計算機)的程式,這些裝置都通過網絡連接配接起來。

java.net

包中 J2SE 的 API 包含有類和接口,它們提供低層次的通信細節。你可以直接使用這些類和接口,來專注于解決問題,而不用關注通信細節。

java.net

包中提供了兩種常見的網絡協定的支援:

  • TCP:

    TCP

    是傳輸控制協定的縮寫,它保障了兩個應用程式之間的可靠通信。通常用于網際網路協定,被稱

    TCP / IP

  • UDP:

    UDP

    是使用者資料報協定的縮寫,一個無連接配接的協定。提供了應用程式之間要發送的資料的資料包。

本教程主要講解以下兩個主題。

  • Socket 程式設計:這是使用最廣泛的網絡概念,它已被解釋地非常詳細。
  • URL 處理:這部分會在另外的篇幅裡講,點選這裡更詳細地了解在 Java 語言中的

    URL

    處理

2.Socket程式設計

套接字使用

TCP

提供了兩台計算機之間的通信機制。 用戶端程式建立一個套接字,并嘗試連接配接伺服器的套接字。

當連接配接建立時,伺服器會建立一個

Socket

對象。用戶端和伺服器現在可以通過對

Socket

對象的寫入和讀取來進行通信。

java.net.Socket

類代表一個套接字,并且

java.net.ServerSocket

類為伺服器程式提供了一種來監聽用戶端,并與他們建立連接配接的機制。

以下步驟在兩台計算機之間使用套接字建立

TCP

連接配接時會出現:

  • 伺服器執行個體化一個

    ServerSocket

    對象,表示通過伺服器上的端口通信
  • 伺服器調用

    ServerSocket

    類的

    accept()

    方法,該方法将一直等待,直到用戶端連接配接到伺服器上給定的端口
  • 伺服器正在等待時,一個用戶端執行個體化一個

    Socket

    對象,指定伺服器名稱和端口号來請求連接配接
  • Socket

    類的構造函數試圖将用戶端連接配接到指定的伺服器和端口号。如果通信被建立,則在用戶端建立一個

    Socket

    對象能夠與伺服器進行通信
  • 在伺服器端,

    accept()

    方法傳回伺服器上一個新的

    socket

    引用,該

    socket

    連接配接到用戶端的

    socket

連接配接建立後,通過使用

I/O

流在進行通信,每一個

socket

都有一個輸出流和一個輸入流,用戶端的輸出流連接配接到伺服器端的輸入流,而用戶端的輸入流連接配接到伺服器端的輸出流。

TCP

是一個雙向的通信協定,是以資料可以通過兩個資料流在同一時間發送.以下是一些類提供的一套完整的有用的方法來實作

socket

3.ServerSocket類的方法

伺服器應用程式通過使用

java.net.ServerSocket

類以擷取一個端口,并且偵聽用戶端請求。

ServerSocket

類有四個構造方法:

方法描述

public ServerSocket(int port) throws IOException

建立綁定到特定端口的伺服器套接字。

public ServerSocket(int port, int backlog) throws IOException

利用指定的

backlog

建立伺服器套接字并将其綁定到指定的本地端口号。

public ServerSocket(int port, int backlog, InetAddress address) throws IOException

使用指定的端口、偵聽

backlog

和要綁定到的本地

IP

位址建立伺服器。

public ServerSocket() throws IOException

建立非綁定伺服器套接字。

建立非綁定伺服器套接字。 如果

ServerSocket

構造方法沒有抛出異常,就意味着你的應用程式已經成功綁定到指定的端口,并且偵聽用戶端請求。

這裡有一些

ServerSocket

類的常用方法:

public int getLocalPort()

傳回此套接字在其上偵聽的端口。

public Socket accept() throws IOException

偵聽并接受到此套接字的連接配接。

public void setSoTimeout(int timeout)

通過指定逾時值啟用/禁用

SO_TIMEOUT

,以毫秒為機關。

public void bind(SocketAddress host, int backlog)

ServerSocket

綁定到特定位址(

IP位址

端口号

)。

4.Socket類的方法

java.net.Socket

類代表用戶端和伺服器都用來互相溝通的套接字。用戶端要擷取一個

Socket

對象通過執行個體化 ,而伺服器獲得一個

Socket

對象則通過

accept()

方法的傳回值。

Socket

類有五個構造方法.

public Socket(String host, int port) throws UnknownHostException, IOException

建立一個流套接字并将其連接配接到指定

主機

上的指定

端口号

public Socket(InetAddress host, int port) throws IOException

IP位址

的指定

端口号

public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException

建立一個套接字并将其連接配接到指定遠端主機上的指定遠端端口。

public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException

建立一個套接字并将其連接配接到指定遠端位址上的指定遠端端口。

public Socket()

通過系統預設類型的

SocketImpl

建立未連接配接套接字

Socket

構造方法傳回,并沒有簡單的執行個體化了一個

Socket

對象,它實際上會嘗試連接配接到指定的伺服器和端口。

下面列出了一些感興趣的方法,注意用戶端和伺服器端都有一個

Socket

對象,是以無論用戶端還是服務端都能夠調用這些方法。

public void connect(SocketAddress host, int timeout) throws IOException

将此套接字連接配接到伺服器,并指定一個逾時值。

public InetAddress getInetAddress()

傳回套接字連接配接的位址。

public int getPort()

傳回此套接字連接配接到的遠端端口。

public int getLocalPort()

傳回此套接字綁定到的本地端口。

public SocketAddress getRemoteSocketAddress()

傳回此套接字連接配接的端點的位址,如果未連接配接則傳回

null

public InputStream getInputStream() throws IOException

傳回此套接字的輸入流。

public OutputStream getOutputStream() throws IOException

傳回此套接字的輸出流。
8

public void close() throws IOException

關閉此套接字。

5.InetAddress類的方法

這個類表示網際網路協定(

IP

)位址。下面列出了

Socket

程式設計時比較有用的方法:

static InetAddress getByAddress(byte[] addr)

在給定原始

IP

位址的情況下,傳回

InetAddress

對象。

static InetAddress getByAddress(String host, byte[] addr)

根據提供的主機名和

IP

位址建立

InetAddress

static InetAddress getByName(String host)

在給定主機名的情況下确定主機的

IP

位址。

String getHostAddress()

IP

位址字元串(以文本表現形式)。

String getHostName()

擷取此

IP

位址的主機名。

static InetAddress getLocalHost()

傳回本地主機。

String toString()

将此

IP

位址轉換為

String

6.Socket用戶端執行個體

如下的

GreetingClient

是一個用戶端程式,該程式通過

socket

連接配接到伺服器并發送一個請求,然後等待一個響應。

// 檔案名 GreetingClient.java
import java.net.*;
import java.io.*;
 
public class GreetingClient
{
   public static void main(String [] args)
   {
      String serverName = args[0];
      int port = Integer.parseInt(args[1]);
      try
      {
         System.out.println("連接配接到主機:" + serverName + " ,端口号:" + port);
         Socket client = new Socket(serverName, port);
         System.out.println("遠端主機位址:" + client.getRemoteSocketAddress());
         OutputStream outToServer = client.getOutputStream();
         DataOutputStream out = new DataOutputStream(outToServer);
 
         out.writeUTF("Hello from " + client.getLocalSocketAddress());
         InputStream inFromServer = client.getInputStream();
         DataInputStream in = new DataInputStream(inFromServer);
         System.out.println("伺服器響應: " + in.readUTF());
         client.close();
      }catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}           

7.Socket服務端執行個體

GreetingServer

程式是一個伺服器端應用程式,使用

Socket

來監聽一個指定的端口。

// 檔案名 GreetingServer.java
import java.net.*;
import java.io.*;
 
public class GreetingServer extends Thread
{
   private ServerSocket serverSocket;
   
   public GreetingServer(int port) throws IOException
   {
      serverSocket = new ServerSocket(port);
      serverSocket.setSoTimeout(10000);
   }
 
   public void run()
   {
      while(true)
      {
         try
         {
            System.out.println("等待遠端連接配接,端口号為:" + serverSocket.getLocalPort() + "...");
            Socket server = serverSocket.accept();
            System.out.println("遠端主機位址:" + server.getRemoteSocketAddress());
            DataInputStream in = new DataInputStream(server.getInputStream());
            System.out.println(in.readUTF());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            out.writeUTF("謝謝連接配接我:" + server.getLocalSocketAddress() + "\nGoodbye!");
            server.close();
         }catch(SocketTimeoutException s)
         {
            System.out.println("Socket timed out!");
            break;
         }catch(IOException e)
         {
            e.printStackTrace();
            break;
         }
      }
   }
   public static void main(String [] args)
   {
      int port = Integer.parseInt(args[0]);
      try
      {
         Thread t = new GreetingServer(port);
         t.run();
      }catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}           

編譯以上兩個 Java 檔案代碼,并執行以下指令來啟動服務,使用

端口号

6066

$ javac GreetingServer.java 
$ java GreetingServer 6066
等待遠端連接配接,端口号為:6066...           

新開一個指令視窗,執行以上指令來開啟用戶端:

$ javac GreetingClient.java 
$ java GreetingClient localhost 6066
連接配接到主機:localhost ,端口号:6066
遠端主機位址:localhost/127.0.0.1:6066
伺服器響應: 謝謝連接配接我:/127.0.0.1:6066
Goodbye!           

上一篇:

序列化

下一篇:

郵件收發
如果對課程内容感興趣,可以掃碼關注我們的

公衆号

QQ群

,及時關注我們的課程更新
Java入門 - 進階教程 - 05.網絡程式設計網絡程式設計
Java入門 - 進階教程 - 05.網絡程式設計網絡程式設計