• 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请求

    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
    ";
    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
    Content-Length:{0}
    ",
    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
    ";
    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
    Content-Length:{0}
    ",
    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服务器的实例,实现结果如图所示:

       

  • 相关阅读:
    Spring -- spring 和 hibernate 整合
    文件:一个任务
    文件:因为懂你,所以永恒
    集合:在我的世界里,你就是唯一
    总结回顾
    快速排序的优化
    快速排序
    归并排序(迭代实现)- 数据结构和算法95
    归并排序(递归实现)- 数据结构和算法94
    堆排序的代码实现
  • 原文地址:https://www.cnblogs.com/hanyinglong/p/3419289.html
Copyright © 2020-2023  润新知