天天看點

ASP.NET本質論第一章網站應用程式學習筆記1

1.統一資源标示符

  1) 格式:協定://主機[.端口号][絕對路徑[?參數]],在Http://www.kencery.com/hyl/index/login中,http表示協定的名稱,www.kencery.com表示主機的位址,可選的端口号沒有出現,那麼,将使用http協定的預設端口号80,絕對路徑為:hyl/index/login,如果沒有提供絕對路徑,那麼,使用預設的絕對路徑/。

  2) .NET中提供的對URL或者URI操作的方法代碼如下:  

1 Uri uri = new Uri("https://www.kencery.com/hyl/index/login");
2 Console.WriteLine(uri.Scheme); //協定的名稱   輸出結果:https
3 Console.WriteLine(uri.Host); //取得Uri位址中的主機部分 輸出結果:www.kencery.com
4 Console.WriteLine(uri.Port); //端口号   輸出結果:80
5 Console.WriteLine(uri.AbsolutePath); //絕對路徑  輸出結果:/hyl/index/login
6 Console.WriteLine(uri.Query); //位址中的參數部分   輸出結果: 
7 Console.ReadLine();      

  3) 浏覽器要找到我們通路的伺服器,需要提供伺服器的網絡位址,在目前的TCP/IP協定下,所謂的伺服器位址其實就是一個IP位址,目前我們使用的是IPV4的位址,每個位址由四個位元組共32位組成,理論上講,可以表示4G的網絡位址,微軟的IP位址是:207.46.19.254,是以我們直接在位址欄中輸入http://207.46.19.254也可以看到微軟的網站。

  4)HTTP協定

    1.當浏覽器尋找到Web伺服器的位址之後,浏覽器将幫助我們把對伺服器的請求轉換為一系列的參數發送給Web伺服器,伺服器收到浏覽器發來的請求參數之後,将會分析這些資料并進行處理,然後向浏覽器回應處理的結果,也就是一些新的資料,浏覽器收到之後,就會解析這些資料,并将他們顯示在浏覽器中。

    2,在浏覽器與Web伺服器之間進行通信的時候,需要雙方都要能夠了解的規範進行通訊,這種程式之間進行通信的語言規範,我們稱之為協定,協定有許多種,根據國際标準化組織ISO的網絡參考模型,程式與程式之間的通信可以分為7種,從低到高依次是:實體層,資料鍊路層,網絡層,傳輸層,會話層,表示層,應用層,每層都有自己對應的協定。

    3.請求微軟網站的請求資訊如圖所示:Http請求

ASP.NET本質論第一章網站應用程式學習筆記1

2.最簡單的Web伺服器

  2.1 網絡插座Socket

    在Unix時代,為了解決傳輸層的程式設計問題,Unix提供了類似于檔案操作的網絡操作方式—Socket,通過Socket,開發人員可以像操作檔案一樣通過打開,寫入,讀取,關閉等操作來完成網絡程式設計,Socket不負責應用層的協定,僅僅負責傳輸層的協定。

    當通過Socket開發網絡應用程式的時候,首先需要考慮所使用的網絡類型,主要包括以下三個方面:

    1)Socket類型,使用網絡協定的類别,IPV4的類型為PF_INET

    2)資料通信的類型,常見的資料報(Sock_DGRAM),資料流(SOCK_STREAM)。

    3)使用網絡協定,比如:TCP協定。

  2.2 在.NET中,System.Net命名空間提供了網絡程式設計的大多數資料類型以及常用操作,其中類型如下:

    1) IPAddress類用來表示一個IP位址

    2) IPEndPoint類用來表示一個IP位址和一個端口号的組合,成為網絡的端口。

    3) System.NET.Sockets命名空間中提供了基于Socket程式設計的資料類型。

    4) Socket類封裝了Socket的操作。常見的操作如下:

      a) Listen:設定基于連接配接通信的Socket進入監聽狀态,并設定等待隊列的長度。

      b) Accept:等待一個新的連接配接,當新連接配接到達的時候,傳回一個針對新連接配接的Socket對象。通過這個新的Socket對象,可與新連接配接通信。

      c) Receive:通過Socket接收位元組資料,儲存到一個位元組數組中,傳回實際接收的位元組數。

      d)  Send:通過Socket發送預先儲存在位元組數組中的資料。

  2.3 通過Socket程式設計建立一個簡單地Web伺服器

1 private static void Main(string[] args)
 2 {
 3     //取得本機的loopbakack網絡位址,即127.0.0.1
 4     IPAddress address = IPAddress.Loopback;
 5     //建立可以通路的端點,49152表示端口号,如果設定為0,表示使用一個空閑的端口号
 6     IPEndPoint endPoint = new IPEndPoint(address, 49152);
 7     //建立Socket,使用IPV4位址,傳輸控制協定TCP,雙向,可靠,基于連接配接的位元組流
 8     Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 9     //将Socket綁定到一個端口上
10     socket.Bind(endPoint);
11     //設定連接配接隊列的長度
12     socket.Listen(10);
13     Console.WriteLine("開始監聽:端口号:{0}", endPoint.Port);
14     while (true)
15     {
16         //開始監聽,這個方法會阻塞線程的執行,直到接收到一個用戶端的連接配接請求
17         Socket client = socket.Accept();
18         //輸出用戶端位址
19         Console.WriteLine("用戶端位址:{0}", client.RemoteEndPoint);
20         //準備讀取用戶端請求的位址,讀取的資料将儲存在一個數組中
21         byte[] buffer = new byte[4096];
22         //接收資料
23         int length = client.Receive(buffer, 4096, SocketFlags.None);
24         //将請求的資料翻譯成UTF-8
25         Encoding utf8 = Encoding.UTF8;
26         string requestString = utf8.GetString(buffer, 0, length);
27         //顯示請求的資訊
28         Console.WriteLine(requestString);
29         //回應的狀态行
30         string statusLine = "HTTP/1.1 200 OK\r\n";
31         byte[] statusLineBytes = utf8.GetBytes(statusLine);
32         //準備發送到用戶端的網頁
33         string responseBody =
34             "<html><head><title>From Socket Server</title></head><body><h1>Hello,World</h1></body></html>";
35         byte[] responseBodyBytes = utf8.GetBytes(responseBody);
36         //回應的頭部
37         string responseHeader = string.Format("Content-type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n",
38                                                 responseBody.Length);
39         byte[] responseHeaderBytes = utf8.GetBytes(responseHeader);
40         //向用戶端發送狀态資訊
41         client.Send(statusLineBytes);
42         //向用戶端發送回應頭
43         client.Send(responseBodyBytes);
44         //頭部和内容的分割行
45         client.Send(new byte[] {13, 10});
46         //向用戶端發送内容部分
47         client.Send(responseBodyBytes);
48         //斷開與用戶端的連結
49         client.Close();
50         if (Console.KeyAvailable)
51         {
52             break;
53         }   
     }
      
54      //關閉伺服器
55      socket.Close();      
57 }      

  2.4 基于TcpListener的Web伺服器

    為了簡化基于TCP協定的監聽程式,.NET在System.Net.Sockets命名空間中提供了TcpListener類,代碼如下:

1 private static void Main(string[] args)
 2 {
 3     //取得本機的loopbakack網絡位址,即127.0.0.1
 4     IPAddress address = IPAddress.Loopback;
 5     //建立可以通路的端點,49152表示端口号,如果設定為0,表示使用一個空閑的端口号
 6     IPEndPoint endPoint = new IPEndPoint(address, 49152);
 7     //建立Socket,使用IPV4位址,傳輸控制協定TCP,雙向,可靠,基于連接配接的位元組流
 8     Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 9     //将Socket綁定到一個端口上
10     socket.Bind(endPoint);
11     //設定連接配接隊列的長度
12     socket.Listen(10);
13     Console.WriteLine("開始監聽:端口号:{0}", endPoint.Port);
14     while (true)
15     {
16         //開始監聽,這個方法會阻塞線程的執行,直到接收到一個用戶端的連接配接請求
17         Socket client = socket.Accept();
18         //輸出用戶端位址
19         Console.WriteLine("用戶端位址:{0}", client.RemoteEndPoint);
20         //準備讀取用戶端請求的位址,讀取的資料将儲存在一個數組中
21         byte[] buffer = new byte[4096];
22         //接收資料
23         int length = client.Receive(buffer, 4096, SocketFlags.None);
24         //将請求的資料翻譯成UTF-8
25         Encoding utf8 = Encoding.UTF8;
26         string requestString = utf8.GetString(buffer, 0, length);
27         //顯示請求的資訊
28         Console.WriteLine(requestString);
29         //回應的狀态行
30         string statusLine = "HTTP/1.1 200 OK\r\n";
31         byte[] statusLineBytes = utf8.GetBytes(statusLine);
32         //準備發送到用戶端的網頁
33         string responseBody =
34             "<html><head><title>From Socket Server</title></head><body><h1>Hello,World</h1></body></html>";
35         byte[] responseBodyBytes = utf8.GetBytes(responseBody);
36         //回應的頭部
37         string responseHeader = string.Format("Content-type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n",
38                                                 responseBody.Length);
39         byte[] responseHeaderBytes = utf8.GetBytes(responseHeader);
40         //向用戶端發送狀态資訊
41         client.Send(statusLineBytes);
42         //向用戶端發送回應頭
43         client.Send(responseBodyBytes);
44         //頭部和内容的分割行
45         client.Send(new byte[] {13, 10});
46         //向用戶端發送内容部分
47         client.Send(responseBodyBytes);
48         //斷開與用戶端的連結
49         client.Close();
50         if (Console.KeyAvailable)
51         {
52             break;
53         }
54     }
55     //關閉伺服器
56     socket.Close();
57 }      

  2.5 基于HttpListener的web伺服器

    為了進一步簡化HTTP協定的監聽器,.NET在命名空間System.Net中提供了HttpListener類,伴随這個對象,.NET提供了一系列相關對象封裝了HTTP的處理工作,注意,這個類使用Http.sys系統元件來完成工作,是以,隻有在Windows XP SP2或者Server2003以上的作業系統中磁能使用。

1 private static void Main(string[] args)
 2 {
 3     //檢查系統是否支援
 4     if (!HttpListener.IsSupported)
 5     {
 6         throw new System.InvalidOperationException("使用HTTPListener必須為Windows XP SP2或者Server 2003以上系統");
 7     }
 8     //注意字首必須以/正斜杠結尾
 9     string[] prefixes = new string[] {"http://localhost:49125/"};
10     //建立監聽器
11     HttpListener listener = new HttpListener();
12     //增加監聽的字首
13     foreach (string s in prefixes)
14     {
15         listener.Prefixes.Add(s);
16     }
17     //開始監聽
18     listener.Start();
19     Console.WriteLine("監聽中。。。。。。");
20     while (true)
21     {
22         //注意:GetContext方法将阻塞線程,直到請求到達
23         HttpListenerContext context = listener.GetContext();
24         //取得請求對象
25         HttpListenerRequest request = context.Request;
26         Console.WriteLine("{0}{1} HTTP/1.1", request.HttpMethod, request.RawUrl);
27         Console.WriteLine("Accept:{0}", string.Join(",", request.AcceptTypes));
28         Console.WriteLine("Accept-Language:{0}", string.Join(",", request.UserLanguages));
29         Console.WriteLine("User-Agent:{0}", request.UserAgent);
30         Console.WriteLine("Accept-Encoding:{0}", request.Headers["Accept-Encoding"]);
31         Console.WriteLine("Connection:{0}", request.KeepAlive ? "Keep_Alive" : "close");
32         Console.WriteLine("Host:{0}", request.UserHostName);
33         Console.WriteLine("Pragma:{0}", request.Headers["Pragma"]);
34         //取得回應的對象
35         HttpListenerResponse response = context.Response;
36         //構造回應内容
37         string responseString =
38             @"<html><head><title>From Socket Server</title></head><body><h1>Hello,World</h1></body></html>";
39         //設定回應頭部内容,成都,編碼
40         response.ContentLength64 = Encoding.UTF8.GetByteCount(responseString);
41         response.ContentType = "text/html;chrset=UTF-8";
42         //輸出回應内容
43         Stream output = response.OutputStream;
44         StreamWriter writer = new StreamWriter(output);
45         writer.Write(responseString);
46         //必須關閉輸出流
47         writer.Close();
48         if (Console.KeyAvailable)
49         {
50             break;
51         }
52     }
53     //關閉伺服器
54     listener.Close();
55     Console.ReadLine();
56 }      

  上面三個關于簡單地模拟了一下Web伺服器的執行個體,實作結果如圖所示:

ASP.NET本質論第一章網站應用程式學習筆記1

   

初心商城:初心商城

作者:韓迎龍(Kencery)    MVC/.NET群:159227188

如果您認為這篇文章還不錯或者有所收獲,您可以通過右邊的“打賞”功能 打賞一杯咖啡,本頁版權歸作者和部落格園所有,歡迎轉載,但未經作者同意必須保留此段聲明,

且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利