小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

寫一個(gè)簡易web服務(wù)器、ASP.NET核心知識(4)

 昵稱10504424 2015-03-17

前言

昨天嘗試了,基于對http協(xié)議的探究,我們用控制臺寫了一個(gè)簡單的瀏覽器。盡管瀏覽器很low,但是對于http協(xié)議有個(gè)更好的理解。

clipboard說了上面這一段,諸位猜到我要干嘛了嗎?(其實(shí)不用猜哈,標(biāo)題里都有,又都不瞎。。。我就是調(diào)侃一下,說些沒營養(yǎng)的笑話。我認(rèn)為這樣能不那么枯燥,盡管不好笑吧,但這不重要?。?/span>

沒錯(cuò),今天要嘗試的東西,是自己寫一個(gè)web服務(wù)器。初衷依舊和昨天一樣,旨在理解一些東西,而不是真的寫出一個(gè)多牛的東西。

第一次嘗試(V1.0)

1.理論支持

其實(shí)關(guān)于http協(xié)議的理論方面我在《寫一個(gè)瀏覽器》的博文中已經(jīng)說過了,這里不再累述了。

這里主要要說的關(guān)于Socket方面的。主要是一個(gè)例子,關(guān)于Socket如何建立服務(wù)端程序的簡單的代碼掩飾。

復(fù)制代碼
       static void Main(string[] args)
        {
            //創(chuàng)建一個(gè)新的Socket,這里我們使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //將該socket綁定到主機(jī)上面的某個(gè)端口
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //啟動(dòng)監(jiān)聽,并且設(shè)置一個(gè)最大的隊(duì)列長度
            socket.Listen(4);
            //到這里我們的Socket已經(jīng)運(yùn)行起來了,但僅僅是運(yùn)行起來,什么都不會(huì)做的!

            Console.WriteLine("Server is ready!");
            Console.Read();
        } 
復(fù)制代碼

打開調(diào)試一口,因?yàn)橐O(jiān)聽某個(gè)端口,windows會(huì)有這樣的一個(gè)提示。點(diǎn)允許就好了。

clipboard[1]

從上面例子看,socket的職責(zé)僅僅是監(jiān)聽4530端口,什么都不會(huì)做的!

就像一個(gè)人的耳朵。他會(huì)聆聽,但是不會(huì)傾訴。職責(zé)所限,我們需要一個(gè)監(jiān)聽4530端口的耳朵。

但是從交流的角度看,web服務(wù)器僅僅能聆聽是不夠的。

請求來了以后(監(jiān)聽到請求以后),我還需要一個(gè)既能聆聽,又能訴說的Socket。去和請求交流。

剛剛那個(gè)socket為啥不能直接交流呢? 不不不,他得繼續(xù)去聆聽新的請求。

2.說說思路

這次實(shí)驗(yàn)的主要思路是這樣的。

1)監(jiān)聽4530端口

2)當(dāng)請求來了以后,我們使用Socket socket = serverSocket.Accept();建立一個(gè)新的socket。

3)新的socket返回一個(gè)字符串給請求方!

完了(讀liao)。

也就是說,我們v1.0版本的web服務(wù)器,不管你如何請求,他都會(huì)返回你同一個(gè)字符串!(任性吧?其實(shí)我挺喜歡就這樣的。)

3.代碼

復(fù)制代碼
static void Main(string[] args)
{
            //我僅負(fù)責(zé)聆聽,因?yàn)槟銇砹?,我就得接著等待下一個(gè)。
            //(據(jù)說注釋寫成這樣的都是妖精!工作時(shí)候這樣寫能被打死不?等我找著工作了我試試)
           Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //綁定監(jiān)聽的端口
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8070));
            //開始聆聽你的請求
            serverSocket.Listen(10);
            while (true)
            {
                Console.WriteLine("等著請求");
                //沒有請求的狀態(tài)下,程序就在這里停留。
                //你來了,serverSocket就會(huì)把你的心愿告訴給一個(gè)新的socket。程序就繼續(xù)執(zhí)行了?。òパ剑乃嚕?/span>
                Socket socket = serverSocket.Accept();
                Console.WriteLine("來了請求");
                using (NetworkStream stream = new NetworkStream(socket))
                using (StreamReader reader = new StreamReader(stream))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Console.WriteLine(line);
                        if (line.Length <= 0)
                        {
                            break;//遇到空行了,請求結(jié)束了不用再等了
                            //如果不break,就一直卡在ReadLine()等著瀏覽器發(fā)后續(xù)的數(shù)據(jù)
                        }
                    }
                }
             
                using (NetworkStream stream = new NetworkStream(socket))
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.WriteLine("HTTP/1.1 200 OK");
                    writer.WriteLine();
                    writer.WriteLine("哎呀,你好,你好!");
                }
                socket.Disconnect(false);
            }
}
復(fù)制代碼

4.調(diào)試

我們就這樣任性的、如qq自動(dòng)回互般的,高冷的一直回答說:“哎呀,你好,你好!”。

clipboard[2]

改進(jìn)(V2.0)

1.改進(jìn)需求

上一個(gè)版本的web服務(wù)器(姑且這么叫著。)根本沒有一點(diǎn)web服務(wù)器的樣子。聊天嘛,總不能一直“呵呵”下去。會(huì)沒朋友的!

所以新的web服務(wù)器改進(jìn)需求如下。

1.能夠獲取請求 路徑

2.能夠根據(jù)請求路徑對應(yīng)的文件,返回響應(yīng)的靜態(tài)頁面!

好歹有個(gè)正經(jīng)人家孩子的樣子嘛,老“呵呵”,成何體統(tǒng)。

我們話不多說,直接開始敲代碼吧!

2.實(shí)現(xiàn)

復(fù)制代碼
static void Main(string[] args)
{
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
            serverSocket.Listen(10);
            while (true)
            {
                Console.WriteLine("等著請求");
                Socket socket = serverSocket.Accept();
                Console.WriteLine("來了請求");
                string firstLine;
                using (NetworkStream stream = new NetworkStream(socket))
                using (StreamReader reader = new StreamReader(stream))
                {
                    //想1.0版本里多出了這么一句。
                    //想想http請求報(bào)文格式吧,第一行有文件路徑的喏!
                    firstLine = reader.ReadLine();
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Console.WriteLine(line);
                        if (line.Length <= 0)
                        {
                            break;//遇到空行了,請求結(jié)束了不用再等了
                            //如果不break,就一直卡在ReadLine()等著瀏覽器發(fā)后續(xù)的數(shù)據(jù)
                        }
                    }
                }
                //獲取請求路徑
                string[] strs = firstLine.Split(' ');
                //url就獲取到了 類似index.html的這樣的串。
                string url = strs[1];

                Console.WriteLine("url=" + url);
                using (NetworkStream stream = new NetworkStream(socket))
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    //為什么要指定絕對路徑呢?想想正常web服務(wù)器里的【物理路徑】是啥意思。應(yīng)該就懂了。
                    string filePath = @"C:\Users\WinterT\Desktop\消息框、JBar" + url;
                    Console.WriteLine("filePath=" + filePath);
                    if (File.Exists(filePath))
                    {
                        writer.WriteLine("HTTP/1.1 200 OK");
                        writer.WriteLine();
                        string html =
                        File.ReadAllText(filePath);
                        Console.WriteLine(html);
                        writer.Write(html);
                    }
                    else
                    {
                        writer.WriteLine("HTTP/1.1 404 NOT FOUND");
                        writer.WriteLine();
                        writer.Write("404,沒有找到");
                    }
                }
                socket.Disconnect(false);
            }
}
復(fù)制代碼

3.調(diào)試

請求的是我電腦里已有的一個(gè)html頁面。成功的顯示出來了!

clipboard[3]

結(jié)束感言

clipboard[4]clipboard[5]clipboard[6]clipboard[7](表示我很開心)

其實(shí)這次實(shí)驗(yàn),得出的結(jié)論依然是http協(xié)議是請求/響應(yīng)式的。傳遞的是文本!

就這個(gè)軟件而言,還有很多需要改進(jìn)的地方。 但這不是重點(diǎn)。重點(diǎn)是理解一些東西,做web服務(wù)器只是形式,而非目的!

PS:剛剛發(fā)現(xiàn),現(xiàn)在補(bǔ)充進(jìn)來。

不知道諸位注意到?jīng)]有。

我的web服務(wù)器,每次我從瀏覽器輸入url發(fā)出一個(gè)請求后,服務(wù)器的控制臺上都會(huì)顯示兩個(gè)請求。

那么多出來的那個(gè)請求是干啥的呢?我們再仔細(xì)看一下圖!

對,沒錯(cuò)。瀏覽器在請求網(wǎng)站圖標(biāo)!

也就是說,我們想做網(wǎng)站圖標(biāo)的話,直接在網(wǎng)站根目錄下放一個(gè)做好的

favicon.ico文件就好了!!

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多