Java 網路程式設計(Socket 程式設計 & URL處理)
阿新 • • 發佈:2019-01-28
- 網路程式設計是指編寫執行在多個裝置(計算機)的程式,這些裝置都通過網路連線起來
- 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()
:返回此套接字連線的端點的地址,如果未連線則返回 nullpublic 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 地址建立 InetAddressstatic 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 內容.....
這篇文章摘抄自菜鳥教程,謝謝您的閱讀