1. 程式人生 > >Java 網路程式設計(Socket 程式設計 & URL處理)

Java 網路程式設計(Socket 程式設計 & URL處理)

  • 網路程式設計是指編寫執行在多個裝置(計算機)的程式,這些裝置都通過網路連線起來
  • java.net包提供兩種常見的網路協議的支援
    • TCP:傳輸控制協議,保障兩個應用程式之間的可靠通訊,通常用於網際網路協議,被稱TCP/IP
    • UDP:使用者資料報協議,一個無連線的協議,提供應用程式之間要傳送的資料的資料包

Socket 程式設計

  • java.net.Socket類代表一個套接字,並且java.net.ServerSocket類為伺服器程式提供了一種監聽客戶端,並與他們建立連線到機制
  • TCP是一個雙向通訊協議,所以資料可以通過兩個資料流在同一時間傳送
  • 伺服器例項化一個ServerSocket物件
    ,表示通過伺服器上的埠通訊
  • 伺服器呼叫ServerSocket類的accept()方法,該方法一直等待,直到客戶端連線到伺服器上給定的埠
  • Socket類的建構函式試圖將客戶端連線到指定的伺服器和埠號,如果通訊被建立,則在客戶端建立一個Socket物件能夠與伺服器進行通訊
  • 在伺服器端,accept()方法返回伺服器上一個新的socket引用,該socket連線到客戶端的socket
  • 連線建立後,通過使用I/O流進行通訊,每一個socket都有一個輸出流和一個輸入流,客戶端的輸出流連線到服務端的輸入流,而客戶端的輸入流連線到服務端的輸出流
  • 伺服器應用程式通過使用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 地址和埠號)
  • 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:返回此套接字的輸出流
    • public void close() throws IOException:關閉此套接字
  • 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
  • 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();
      }
   }
}
  • 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() + "\nbyebye");
            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 -encoding UTF-8 GreetingServer.java 
$ java GreetingServer 6066
等待遠端連線,埠號為:6066...
<em>Socket timed out!

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

$ javac -encoding UTF-8 GreetingClient.java 
$ java GreetingClient localhost 6066
連線到主機:localhost ,埠號:6066
遠端主機地址:localhost/127.0.0.1:6066
伺服器響應: 謝謝連線我:/127.0.0.1:6066
byebye

Java URL 處理

  • URL(Uniform Resource Locator)統一資源定位符,俗稱網頁地址,表示網際網路上的資源
  • protocol://host:port/path?query#fragment:protocol協議可以是HTTP、HTTPS、FTP和File,port是埠號(預設埠號為80),path為檔案路徑及檔名,query為請求引數,fragment為定位位置
  • URL類方法:java.net.URL提供了豐富的URL構建方法,並可以通過java.net.URL來獲取資源
  • 建立URL
    • public URL(String protocol, String host, int port, String file) throws MalformedURLException
    • public URL(String protocal, String host, String file) throws MalformedURLException:預設埠
    • public URL(String url) throws MalformedURLException
    • public URL(URL context, String url) throws MalformedURLException:使用基地址和相對URL建立
  • 訪問URL的各個部分
    • public String getPath():路徑,如/index.html
    • public String getQuery():請求引數,如language=cn
    • public String getAuthority():獲取此URL的授權部分,如www.runoob.com
    • public int getPort():埠,如-1
    • public int getDefaultPort():預設埠,如80
    • public String getProtocol():如http
    • public String getHost():主機名,如www.runoob.com
    • public String getFile():檔名及請求引數,如/index.html?language=cn
    • public String getRef():獲取此URL的錨點(也稱“引用”),定位位置,#後面的
    • public URLConnection openConnection() throws IOException:開啟一個URL連線,並執行客戶端訪問資源
  • URLConnections 類方法
  • openConnection():返回一個java.net.URLConnection
    • Object getContent():檢索URL連結內容
    • Object getContent(Class[] classes):檢索URL連結內容
    • String getContentEncoding():返回頭部content-encoding欄位值
    • int getContentLength():返回頭部content-length欄位值
    • String getContentType():返回頭部content-type欄位值
    • int getLassModified():返回頭部last-modified欄位值
    • long getExpiration():返回頭部expires欄位值
    • long getIfModifiedSince():返回物件的ifModifiedSince欄位值
    • public void setDoInput(boolean input):如果打算使用URL連線進行輸入,將DoInput設為true;不打算使用設為false。預設值為true
    • public void setDoOutput(boolean output):如果打算使用URL連線進行輸出,將DoOutput設為true;不打算使用設為false。預設值為false
    • public InputStream getInputStream() throws IOException:返回URL的輸入流,用於讀取資源
    • public OutputStream getOutputStream() throws IOException:返回URL的輸出流,用於寫入資源
    • public URL getURL():返回URLConnection物件連線的URL
  • 例項:URL採用了HTTP 協議。 openConnection 返回HttpURLConnection物件。
// URLConnDemo.java

import java.net.*;
import java.io.*;

public class URLConnDemo {
   public static void main(String[] args) {
      try {
         URL url = new URL("http://www.runoob.com");
         URLConnection urlConnection = url.openConnection();
         HttpURLConnection connection = null;
         if (urlConnection instanceof HttpURLConnection) {
            connection = (HttpURLConnection) urlConnection;
         } else {
            System.out.println("請輸入 URL 地址");
            return;
         }
         BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
         String urlString = "";
         String current;
         while ((current = in.readLine()) != null) {
            urlString += current;
         }
         System.out.println(urlString);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}
$ javac URLConnDemo.java 
$ java URLConnDemo
.....輸出 HTML 內容.....

這篇文章摘抄自菜鳥教程,謝謝您的閱讀