第一次尝试(V1.0)

1.理论支持

这里主要要说的关于Socket方面的。主要是一个例子,关于Socket如何建立服务端程序的简单的代码。

       static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            socket.Listen(4);
            //到这里我们的Socket已经运行起来了,但仅仅是运行起来,什么都不会做的!

            Console.WriteLine("Server is ready!");
            Console.Read();
        } 

打开调试一口,因为要监听某个端口,windows会有这样的一个提示。点允许就好了。

从上面例子看,socket的职责仅仅是监听4530端口,什么都不会做的!

就像一个人的耳朵。他会聆听,但是不会倾诉。职责所限,我们需要一个监听4530端口的耳朵。

但是从交流的角度看,web服务器仅仅能聆听是不够的。

请求来了以后(监听到请求以后),我还需要一个既能聆听,又能诉说的Socket。去和请求交流。

刚刚那个socket为啥不能直接交流呢? 不不不,他得继续去聆听新的请求。

2.说说思路

这次实验的主要思路是这样的。

1)监听4530端口

2)当请求来了以后,我们使用Socket socket = serverSocket.Accept();建立一个新的socket。

3)新的socket返回一个字符串给请求方!

也就是说,我们v1.0版本的web服务器,不管你如何请求,他都会返回你同一个字符串!(任性吧?其实我挺喜欢就这样的。)

3.代码

static void Main(string[] args)
{
            //我仅负责聆听,因为你来了,我就得接着等待下一个。
           Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定监听的端口
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8070));
            //开始聆听你的请求
            serverSocket.Listen(10);
            while (true)
            {
                Console.WriteLine("等着请求");
                //没有请求的状态下,程序就在这里停留。
                //你来了,serverSocket就会把你的心愿告诉给一个新的socket。程序就继续执行了!
                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;//遇到空行了,请求结束了不用再等了
                            //如果不break,就一直卡在ReadLine()等着浏览器发后续的数据
                        }
                    }
                }

                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);
            }
}

4.调试

我们就这样任性的、如qq自动回互般的,高冷的一直回答说:“哎呀,你好,你好!”。

改进(V2.0)

1.改进需求

新的web服务器改进需求如下。

1.能够获取请求 路径

2.能够根据请求路径对应的文件,返回响应的静态页面!

2.实现

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请求报文格式吧,第一行有文件路径的喏!
                    firstLine = reader.ReadLine();
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        Console.WriteLine(line);
                        if (line.Length <= 0)
                        {
                            break;//遇到空行了,请求结束了不用再等了
                            //如果不break,就一直卡在ReadLine()等着浏览器发后续的数据
                        }
                    }
                }
                //获取请求路径
                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服务器里的【物理路径】是啥意思。应该就懂了。
                    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);
            }
}

3.调试

请求的是我电脑里已有的一个html页面。成功的显示出来了!

PS:刚刚发现,现在补充进来。

不知道诸位注意到没有。

我的web服务器,每次我从浏览器输入url发出一个请求后,服务器的控制台上都会显示两个请求。

那么多出来的那个请求是干啥的呢?我们再仔细看一下图!

对,没错。浏览器在请求网站图标!

也就是说,我们想做网站图标的话,直接在网站根目录下放一个做好的

favicon.ico文件就好了!!

写一个简易web服务器、ASP.NET核心知识(4)--转载的更多相关文章

  1. 写一个简易浏览器、ASP.NET核心知识(3)

    前言 先在文章前面说好了,省得大家发现我根本没有这样的头发,duang的一下一堆人骂我. 这篇文章的标题有点大,其实挺low的,我需要在开头解释一下.我这里只想写一个小的控制台,旨在模拟浏览器的htt ...

  2. 写一个简易web服务器、ASP.NET核心知识(4)

    前言 昨天尝试了,基于对http协议的探究,我们用控制台写了一个简单的浏览器.尽管浏览器很low,但是对于http协议有个更好的理解. 说了上面这一段,诸位猜到我要干嘛了吗?(其实不用猜哈,标题里都有 ...

  3. 自己实现一个简易web服务器

    一个web服务器是网络应用中最基础的环节. 构建需要理解三个内容: 1.http协议 2.socket类 3.服务端实现原理 1.1 HTTP http请求 一般一个http请求包括以下三个部分: 1 ...

  4. Socket 初识 用Socket建立一个简易Web服务器

    摘自<Asp.Net 本质论>作者:郝冠军 //在.Net中.system.Net命名空间提供了网络编程的大多数数据据类型以及常用操作,其中常用的类型如下: /* IPAddress 类表 ...

  5. Cookie详解、ASP.NET核心知识(7)

    无状态的http协议 1.回顾http协议 Http协议是请求响应式的,有请求才有响应,是无状态的,不会记得上次和网页“发生了什么”. 关于http协议的这种特点,黑兔在前面的这三篇博文中进行了详细的 ...

  6. IIS Web 服务器/ASP.NET 运行原理基本知识概念整理 转

    转http://www.cnblogs.com/loongsoft/p/7272830.html IIS Web 服务器/ASP.NET 运行原理基本知识概念整理  前言:      记录 IIS 相 ...

  7. 一不小心写了个WEB服务器

    开场 Web服务器是啥玩意? 是那个托管了我的网站的机器么? No,虽然那个也是服务器,但是我们今天要说的Web服务器主要是指像IIS这样一类的,用于处理request并返回response的工具,没 ...

  8. 如何快速建立一个测试资源Web服务器及异步获取资源(Unity3D)

    背景 1.最近看了几位专栏作家的文章,几篇提到了资源通过网络的动态获取.如何建立一个快速的测试环境,不免是一个问题,也就最简单的就是假设http服务器了,微软系的当然首选的IIS了,别的也能用阿帕奇或 ...

  9. 深入理解Tornado——一个异步web服务器

    本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...

随机推荐

  1. .NET基础拾遗(3)字符串、集合和流3

    三.流和序列化 3.1 流概念及.NET中常见流 无论什么信息,文字,声音,图像,只要进入了计算机就都被转化为数字,以数字方式运算.存储.由于计算机中使用二进制运算,因此数字只有两个:0 与 1,就是 ...

  2. <经验杂谈>C#/.Net字符串操作方法小结

    字符串操作是C#中最基本的.最常见的.也是用的最多的,以下我总结 了几种常见的方法 1.把字符串按照分隔符转换成 List /// <summary> /// 把字符串按照分隔符转换成 L ...

  3. IL(Intermediate Language)

    释义: IL是.NET框架中中间语言(Intermediate Language)的缩写.使用.NET框架提供的编译器可以直接将源程序编译为.exe或.dll文件,但此时编译出来的程序代码并不是CPU ...

  4. 未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序

    运行时出现了错误,提示未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序. 这个问题的原因是64位PC上安装了Office的32位版本,所以Micro ...

  5. Tornado模块分类和各模块之间的关系

    1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 tornado.https ...

  6. curl 基本使用简介

    curl是Linux下一个非常著名的下载库,通过这个库,可以很简单的实现文件的下载等操作.看一个简单的例子: #include <curl/curl.h> #include <std ...

  7. [Python shelve模块Error]bsddb.db.DBPageNotFoundError: (-30986, 'DB_PAGE_NOTFOUND: Requested page not found')

    在用scrapy抓数据,用shelve保存时出现了这个Error,目标是储存一串unicode字符串组成的列表,exception代码是tempbase['joke']=joke_list,测试只要j ...

  8. C语言--位运算符

    一.位运算符 1.按位与:& 1> 功能 * 只有对应的两个二进制位为1时,结果位才为1,否则为0 * 举例:10用二进制表示为1010,  7用二进制表示为0111.对两个数值进行&a ...

  9. 异步编程设计模式Demo - PrimeNumberCalculator

    using System; using System.Collections; using System.Collections.Specialized; using System.Component ...

  10. 163k地方门户网站系统js小Bug

    163k地方门户网站系统后台在Firefox下无法通过选择区域来获取相对应的地段,IE浏览器下无些问题. Firebug提示错误为: ReferenceError: requestdataquyu i ...