java中講講URL的用法

URL類的實例
馬克-to-win:URL(Uniform Resource Locator-----一致資源查找器)它用來指向Internet上的資源文件,比如 http://java.sun.com:8080/docs/introdiction.htm net包中的URL類提供API來訪問Internet上的信息。
比如以上的URL中:馬克- to-win:馬克 java社區(qū):防盜版實名手機尾號: 73203。
1)協(xié)議:http
2)IP 地址或主機名:java.sun.com
3)端口號:8080
4)實際文件路徑:docs/introdiction.htm



例:2.4.1
/*no need to have network through to run the program.*/
import java.net.*;
import java.io.*;
public class TestMark_to_win {
    public static void main(String[] args) throws Exception {
        /* Class URL represents a Uniform Resource Locator, a pointer to a
         * "resource" on the World Wide Web. A resource can be something as
         * simple as a file or a directory, public URL(String spec)throws
         * MalformedURLException: Creates a URL object from the String
         * representation.
         */
        URL aURL = new URL("http://java.sun.com:8080/docs/books/"
                + "tutorial/index.html");
        System.out.println("protocol = " + aURL.getProtocol());
        System.out.println("host = " + aURL.getHost());
        System.out.println("filename = " + aURL.getFile());
        System.out.println("default port = " + aURL.getDefaultPort());
        System.out.println("port = " + aURL.getPort());
    }
}

輸出結(jié)果:

protocol = http
host = java.sun.com
filename = /docs/books/tutorial/index.html
default port = 80
port = 8080




例:2.4.2

/* This program needs an open connection to run.
*/
import java.net.*;
import java.io.*;
import java.util.*;
public class TestMark_to_win {
    public static void main(String[] args) throws Exception {
        URL yahoo = new URL("https://www.oracle.com/index.html");
        /* public URLConnection openConnection() throws IOException: Returns a
         * URLConnection object that represents a connection to the remote
         * object referred to by the URL.
         */
        URLConnection yahooConnection = yahoo.openConnection();
        /* public long getLastModified() Returns the value of the last-modified
         * header field. The result is the number of milliseconds since January
         * 1, 1970 GMT.
         */
        System.out.println("content LastModified"
                + new Date(yahooConnection.getLastModified()));
        /*public InputStream getInputStream()throws IOException: Returns an
         * input stream that reads from this open connection.
         */
        // DataInputStream in = new
        // DataInputStream(yahooConnection.getInputStream());
        BufferedReader in = new BufferedReader(new InputStreamReader(
                yahooConnection.getInputStream()));
        String inputLine;
        for (int i = 0; i < 25; i++) {
            inputLine = in.readLine();
            System.out.println(inputLine);
        }
        in.close();
    }
}

輸出結(jié)果:

content LastModifiedTue Mar 27 06:23:25 CST 2018


<!DOCTYPE html>

<html lang="en-US" class="no-js">

<!-- BEGIN:  Compass/HomePage3 -->

<!--  BEGIN:  Compass/HomePage3/Head-HTML -->

<head>

    <title>Oracle | Integrated Cloud Applications and Platform Services</title>
    <meta name="Title" content="Oracle | Integrated Cloud Applications and Platform Services">
  
        <meta name="Description" content="Oracle offers a comprehensive and fully integrated stack of cloud applications and platform services.">
  
    <meta name="Keywords" content="enterprise, applications, software, database, middleware, fusions, business, hardware, Oracle">  
  
  
    <meta name="robots" content="index, follow">






后序及提高:
 
我們先給大家普及一下同步和異步的概念。 引自百度百科:同步指兩個或兩個以上隨時間變化的量在變化過程中保持一定的相對關(guān)系。
同步(英語:Synchronization),指對在一個系統(tǒng)中所發(fā)生的事件(event)之間進行協(xié)調(diào),在時間上出現(xiàn)一致性與統(tǒng)一化的現(xiàn)象。例如,你想將32軌的音頻信號錄制在兩臺16軌磁帶機上,則這兩個磁帶機的磁帶傳送軸就需要鎖定在一起,這個過程就稱為同步。如果這兩個設(shè)備沒有進行同步,無論它們開始的時間多么一致,也會由于兩臺設(shè)備機械結(jié)構(gòu)的差異而產(chǎn)生時間漂移 。


異步是指用戶程序執(zhí)行IO操作后便開始做自己的事情,當IO操作已經(jīng)完成的時候,會得到IO完成的通知。用戶程序再接著干。一點兒事兒都不耽誤。

心跳,長連接,短連接的關(guān)系: 連接建立后,如果不斷開連接,缺省就是“長連接”,不需要發(fā)送數(shù)據(jù)來保持連接。但網(wǎng)上總說要發(fā)“心跳”來維持長連接?為什么?因為有些監(jiān)聽所有端口的防火墻或者電腦管理軟件會把超過一定時間沒有數(shù)據(jù)傳輸?shù)倪B接當作死連接,這些軟件會自動將死連接斷開。當有心跳時,不會被這類軟件當做死連接。短連接表示當需要與目標通信時創(chuàng)建連接,通訊一結(jié)束立刻斷開。

TCP設(shè)計內(nèi)部包含了心跳信號。 但是這個心跳信號和平臺相關(guān),且默認關(guān)閉。我們盡量不要依賴這個功能。

udp用于傳輸視頻流,音頻流或傳感器流等,少傳數(shù)據(jù)沒事。大不了花屏,沙沙聲等。如需確認對方還在線,則也需心跳。有時在你的手機上可以設(shè)置一個指示燈,如對方在線,可讓等亮著,如不在線了,可讓燈滅著。比如有時心情不好,即使在線,也不說話。所以沒數(shù)據(jù),但有心跳。

bio,nio和AIO區(qū)別:
馬克-to-win:我們這章講的io,實際上是bio,即blocked io(阻塞式io)。sun公司推出bio以后,用戶馬上就反應(yīng),這種bio在多用戶時效率比較低。sun公司在1.4版本馬上推出了nio,所謂的new io和后來的AIO(異步IO)。

AIO異步非阻塞IO:
   在此種模式下,用戶進程只需要發(fā)起一個IO操作然后立即返回,等IO操作真正的完成 以后,應(yīng)用程序會得到IO操作完成的通知,此時用戶進程只需要對數(shù)據(jù)進行處理就好了,因為真正的IO讀取或者寫入操作已經(jīng)由 內(nèi)核完成了。

這么看貌似異步應(yīng)該比同步的效率高,但是實際性能測下來,并不一定是這樣。因為異步要想完成,需要一些額外的線程去工作,這一定會花費額外的資源。

馬克-to-win:后來在實際的工作當中,人們發(fā)現(xiàn)nio好是好,但使用起來非常困難。有的工程師花了半年以上的時間,終于把自己的nio系統(tǒng)磨合的非常精湛了。突然發(fā)覺java界又出了一個新的東西,叫做netty。就是有人覺得nio不好使,把他封裝成了一個新技術(shù)叫netty。那些使用nio的工程師大呼太坑人了。后來很多人就轉(zhuǎn)向了netty。使了一段時間,發(fā)覺業(yè)內(nèi)又出了一個新的東西叫vert.x。這個技術(shù)是又把netty封裝了一下。里面還有一些aio的東西。這就是java行業(yè)狀況。更新?lián)Q代非常快。 

我們的策略是把bio學好,基礎(chǔ)打牢,之后什么在當時找工作時流行學什么。這就是我的前沿課程有幾十門的原因。




作業(yè):
1) 查找某個www.microsoft.com的IP地址。
2)檢查http://www.microsoft.com:8080/docs/books/屬性。
3)把www.263.com的內(nèi)容前三行存在一個文件中。
4)用Socket和datagram, 同時實現(xiàn)密碼驗證。

課外作業(yè):
5)醫(yī)院系統(tǒng):肚子疼可能是什麼???感冒?結(jié)石?(在服務(wù)器端有一文件存著這些信息)
6)請做一個Web服務(wù)器,客戶端能打印出一個html文件。

大作業(yè):
編寫仿安卓的網(wǎng)絡(luò)異步回調(diào)底層實現(xiàn)代碼(AsynNetUtils和handler等),思路:網(wǎng)上有很多異步回調(diào)代碼,但都是在同一臺機器上,找不到在不同機器之間如何異步回調(diào)?這里提供一個思路,客戶端在主線程發(fā)送完消息以后,(啟動一額外線程去監(jiān)聽端口動向,當有數(shù)據(jù)進來時,就回調(diào)自己的某一方法即可)同時主線繼續(xù)該干什么干什么。編寫時可參考我參考目錄下的網(wǎng)頁。

項目一:
做一個類似百度后端爬蟲的程序。
在bat3 家巨頭公司中,騰訊和阿里的程序的理念并不難理解,阿里主要是電子商務(wù)網(wǎng)站,我們在后面的網(wǎng)站學習當中,可以模仿制作類似這樣的項目。騰訊的聊天兒程序我們可以在后面的課外閱讀當中看到。最后只剩下百度的后臺爬蟲程序,貌似比較難做。我們這個項目的目標就是做這件事。爬蟲的原理是這樣的,給定一個網(wǎng)頁,我們通過解析,發(fā)現(xiàn)里面有五個url,先把這五個url放在未完成url隊列里,我們可以按照寬度搜索的算法,把第一個url網(wǎng)頁下載下來,把他里面的六個 url再放在未完成url隊列里,處理過的url放在數(shù)據(jù)庫中,把那個url的標題和關(guān)鍵字甚至內(nèi)容也都存下來。當用戶在瀏覽器中輸入關(guān)鍵字時,你就在數(shù)據(jù)庫中找到符合關(guān)鍵字的url,把它返回回來,當用戶點擊你的url時,用戶就可以進入網(wǎng)頁了。




項目2:
做一個類似于tomcat的服務(wù)器。在客戶端的窗口里敲入192.168.1.4:8888/servlet1 mark就能執(zhí)行另外一臺機器上,我們監(jiān)聽8888端口的服務(wù)器程序,它會用反射方法執(zhí)行bin目錄下的servlet1的doGet方法接受mark作為輸入?yún)?shù),且返回hello mark作為返回值返回到客戶端機器上。
拓展思考,如果輸入?yún)?shù)是一段代碼的話,你的doGet方法,完全可以上一章的發(fā)明自己語言一樣,把代碼寫入到一個文件當中,運行它,這就是后門的原理。我們的課程不討論后門的制作,但通過我上面對后門原理的提及,我們重點要講的是對后門的防范。如果你的公司把程序外包出去,外包程序員設(shè)計一個后門,他緊接著可以再制作一段木馬,于是就可以肆意妄為了。對后門的防范,比如他可以在doGet當中,加上一個參數(shù)判斷,比如當有mark這個參數(shù)值時,才運行他那個后門程序。正常的誰也不會用這個參數(shù)。360等防病毒軟件,也會認為你這個程序,就是正常的用戶邏輯,也查不出來。所以最后的結(jié)論是,如果想防后門,唯有進行源代碼級別行行篩查。才能徹底杜絕后門。接著咱們講木馬。最新的木馬完全可以用純javascript編寫。javascript完全正規(guī)的放在網(wǎng)頁當中。不用額外下載任何東西。結(jié)論,要想防木馬,所以盡量不要訪問非正規(guī)網(wǎng)站。但如果一個正規(guī)網(wǎng)站被黑客破解,把網(wǎng)頁中間加了一段兒javascript。那你就只能自認倒霉了。


課外閱讀:
以下的例子,是一個服務(wù)器對多個客戶端。我們的客戶端程序可以運行很多遍,代表多個客戶。

/*in this frame work, many clients can access the server with many thread and many socket using only one port,
bbb client use bbb socket with bbb thread, by default, one port can accept 50 socket. */


import java.net.ServerSocket;
import java.io.*;
import java.net.Socket;

public class ThreadServers {

public static void main(String[] args) {
try {
/* public ServerSocket(int port)
throws IOExceptionCreates a server socket, bound to the specified port.
The maximum queue length for incoming connection indications (a request to connect) is set to 50. If a connection indication
arrives when the queue is full, the connection is refused.


public ServerSocket(int port,int backlog)
throws IOException Creates a server socket and binds it to the specified local port number, with the specified backlog.
The maximum queue length for incoming connection indications (a request to connect) is set to the backlog parameter. If a connection
indication arrives when the queue is full, the connection is refused.

*/
ServerSocket ss = new ServerSocket(8089);
for(;;){
/* here this ServerSocket can accept unlimited client socket.every time after
it accept one, it just come back from the loop, and block here on accept statement.
a new client corresponds to a new socket */
Socket s = ss.accept();
/* this reader get data from socket, then print in the console.
a new client corresponds to a new thread */
ReadThread reader = new ReadThread(s);
// WriteThread writer = new WriteThread(s);

/* WriteThread get the input from console, then write it to the network. */
reader.start();
/*in this case, we have to comment out the following statement because if there
are two clients, if we type in characters in the console, which clients do we
type in to send out to? so the example is made easier not to server to send
out, to make it work, you can make the server to pop up two windows, then one window
corresponds to one client, in window, if you type in some characters, you send them to this client. */
// writer.start();
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}

}

 




以下是客戶端程序:

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

public class ThreadClients {

public static void main(String[] args) {
Socket s = null;
try {
/*a new client corresponds to a new socket*/
s = new Socket("localhost", 8089);
/* this reader get data from socket, then print out in the console. */
/* WriteThread get the input from console, then write it to the network. */
// ReadThread reader = new ReadThread(s);
/*a new client corresponds to a new thread*/
WriteThread writer = new WriteThread(s);
// reader.start();
writer.start();
}
catch (Exception ex) {
ex.printStackTrace();
}


}

}

 

/*this reader get data from socket, then print in the console. */


import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.*;

public class ReadThread extends Thread {
private Socket socket;
public ReadThread(Socket socket) {
this.socket = socket;
}
public void run(){
try {
BufferedReader in = new BufferedReader
(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(true){
String line = in.readLine();
out.println(line+" coming back from server");
System.out.println(line);
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}

 

/*WriteThread get the input from console, then write it to the network.*/




import java.net.Socket;
import java.io.PrintWriter;
import java.io.*;

public class WriteThread extends Thread {
private Socket socket;
public WriteThread(Socket socket) {
this.socket = socket;
}
public void run(){
try {
/*PrintWriter(OutputStream out, boolean autoFlush)
Create a new PrintWriter from an existing OutputStream.
public PrintWriter(Writer out,boolean autoFlush) Create a new PrintWriter.
autoFlush - A boolean; if true, the println() methods will flush the output buffer */
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader inn = new BufferedReader
(new InputStreamReader(socket.getInputStream()));
BufferedReader in =new BufferedReader(new InputStreamReader(System.in));
for(;;){
String line = in.readLine();
out.println(line);
String linen = inn.readLine();
System.out.println(linen);

}
}
catch (IOException ex) {
}
}
}

 
when run,start server, then start several clients.