標籤:
一:瀏覽器如何請求資料基本原理
基本原理:
當瀏覽器輸入地址向伺服器請求資料時,實際上瀏覽器會在內部建立一個Socket對象,把http請求報文轉變成byet[]位元組,然後調用Socket的方法把這些資料發送到伺服器的,例如請求www/baidu.com的網域名稱來會解析成對應的IP地址,解析成:http://202.108.22.5 :80/login.aspx 瀏覽器在解析到IP地址後,做的第二步就是對指定的URL進行HTTP封裝,把URL封裝成http報文,瀏覽器把URL封裝成HTTP報文後,第三步做的事情就是將這個HTTP請求報文發送到伺服器
瀏覽器在解析IP地址時流程:
在網路上訪問網站,要首先通過DNS伺服器把網路網域名稱(www.XXXX.com)解析成61.XXX.XXX.XXX的IP地址後,我們的電腦才能訪問。要是對於每個網域名稱請求我們都要等待網域名稱伺服器解析後返回IP資訊,這樣訪問網路的效率就會降低,而Hosts檔案就能提高解析效率。根據Windows系統規定,在進行DNS請求以前,Windows系統會先檢查自己的Hosts檔案中是否有這個地址映射關係,如果有則調用這個 IP地址映射,如果沒有再向已知的DNS伺服器提出網域名稱解析。也就是說Hosts的請求層級比DNS高。
如何修改Host檔案:
找到電腦中C:\WINDOWS\system32\drivers\etc\hosts檔案,在檔案末尾加入如所示的ip與網域名稱:
然後在瀏覽器中輸入www.taobao.comj就出現了如的效果,至於作用,你懂得!!!二:在瀏覽器訪問本地(Tomcat)伺服器
1:開啟tomcat =》點擊在tomcat主目錄下的apache-tomcat-7.0.50\bin中的startup.bat
2:在瀏覽器輸入本地的瀏覽地址http://localhost:8888/myweb/ ==》我這裡修改了連接埠為8888 一般是8080 就可以看到效果了
三:在瀏覽器中訪問自訂的伺服器
伺服器代碼:==》注意最後一定要關閉Socket..
package Demo1;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class Demo1{ public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(12346); //擷取用戶端對象 Socket s = ss.accept();// BufferedReader br = new BufferedReader(new InputStreamReader(// s.getInputStream()));//// String line = null;//// while ((line = br.readLine()) != null)// {// System.out.println(line);//這裡不能用這樣的方法,會導致伺服器回傳不了資料集,瀏覽器並沒有Socket結束標記// } //讀取瀏覽器發送的資料 InputStream in = s.getInputStream(); byte[] b = new byte[1024]; int len =in.read(b); System.out.println(new String(b,0,len)); //給瀏覽器發送資料 PrintWriter pw = new PrintWriter(s.getOutputStream(),true); pw.println("歡迎光臨李鵬的伺服器"); pw.close(); // 給瀏覽器發送資料 /* OutputStream out = s.getOutputStream(); out.write("歡迎訪問".getBytes()); out.flush();*/ in.close(); s.close(); ss.close(); }}伺服器代碼
在瀏覽器輸入:http://localhost:12345/
就可以看到我們的伺服器端給用戶端發送了資料,
而伺服器端也接受到了瀏覽器傳過來的資料,
這樣我們就可以理解他們的工作原理了...
四:在eclipse下訪問Tomcat伺服器
如果不知道如何寫和他一樣的http://localhost:8888/myweb/mail.html 的頭資訊檔時,可以利用上面第三種的方式在瀏覽器輸入:http://localhost:12345/myweb/mail.html ,可以看到瀏覽器中提交資訊
GET /myweb/mail.html HTTP/1.1
Host: localhost:12345 ==》將這裡的12345修改為8888
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8 ==》別忘了加兩行空格,否則有錯
然後在自己定義的瀏覽器中,給伺服器寫入資料,再讀取伺服器的資料
用戶端代碼:
package Demo1;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.InetAddress;import java.net.Socket;import java.net.UnknownHostException;public class Demo1{ public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket(InetAddress.getByName("10.2.156.26"),8888); PrintWriter pw = new PrintWriter(s.getOutputStream(),true); pw.println("GET /myweb/mail.html HTTP/1.1"); pw.println("Host: localhost:8888"); pw.println("Connection: keep-alive"); pw.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); pw.println("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"); pw.println("Accept-Encoding: gzip,deflate,sdch"); pw.println("Accept-Language: zh-CN,zh;q=0.8"); pw.println(""); pw.println(""); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line = br.readLine())!=null) { System.out.println(line); } br.close(); pw.close(); s.close(); }}用戶端代碼
結果:
其中:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"995-1369649706000"
Last-Modified: Mon, 27 May 2013 10:15:06 GMT
Content-Type: text/html
Content-Length: 995
Date: Mon, 10 Aug 2015 12:34:35 GMT
這些是響應的頭資訊,在瀏覽器看不到的,而其他代碼就由瀏覽器接收到然後解析成為了一個頁面
五:進階的訪問伺服器的方法
通過封裝為URL對象來訪問網頁
java代碼:
package Demo1;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;public class Demo1{ public static void main(String[] args) throws IOException { String path = "http://10.2.156.26:8888/myweb/mail.html?name=aa"; URL url = new URL(path); /*System.out.println(url.getProtocol());//http System.out.println(url.getHost()); //10.2.156.26 System.out.println(url.getPort()); //8888 System.out.println(url.getPath());// /myweb/mail.html System.out.println(url.getFile());// /myweb/mail.html?name=aa */ URLConnection conn = url.openConnection(); //讀取伺服器端返回的資料 InputStream in = conn.getInputStream(); byte[] arr = new byte[1024]; int len = in.read(arr); System.out.println(new String(arr,0,len)); }}代碼
結果:
可以看到這裡是沒有響應的頭資訊的..
六:綜合應用==》爬蟲(擷取到網頁中所有的郵箱)
代碼:
public class Demo1{ /** * 實現網頁爬蟲 */ public static void main(String[] args) throws IOException { // getEmails(); getEmail(); } // 從網路上的網頁擷取郵箱 public static void getEmail() throws IOException { String path = "http://localhost:8888/myweb/mail.html"; URL url = new URL(path); URLConnection conn = url.openConnection(); InputStream in = conn.getInputStream();// 讀取伺服器端返回的mail.html檔案的資料 BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8")); String regex = "\\[email protected]\\w+(\\.\\w+)+"; Pattern p = Pattern.compile(regex); String line = null; while ((line = br.readLine()) != null) { // 使用Matcher對象從讀取的一行中擷取符合郵箱規則的內容 //System.out.println(line); Matcher m = p.matcher(line); while (m.find()) { System.out.println(m.group()); } } } // 從本地檔案中擷取所有的郵箱 public static void getEmails() throws IOException { // 建立讀取本地檔案的讀取流 BufferedReader br = new BufferedReader( new FileReader("file\\mail.html")); String regex = "\\[email protected]\\w+(\\.\\w+)+"; Pattern p = Pattern.compile(regex); String line = null; while ((line = br.readLine()) != null) { // 使用Matcher對象從讀取的一行中擷取符合郵箱規則的內容 Matcher m = p.matcher(line); while (m.find()) { System.out.println(m.group()); } } br.close(); }}爬蟲代碼
結果:
Java 自訂用戶端與伺服器