zoukankan      html  css  js  c++  java
  • 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端

    接上文 多线程编程学习笔记——使用异步IO

    二、   编写一个异步的HTTP服务器和客户端

    本节展示了如何编写一个简单的异步HTTP服务器。

     1.程序代码如下。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks; 
    
    namespace ThreadIODemo
    {
    
        class Program
        { 
    
            static void Main(string[] args)
            {
    
                Console.WriteLine("--创建简单Web服务示例 -- ");
                var server = new AsyncHttpServer(port: 1234);
                var t = Task.Run(() => server.Start());
                Console.WriteLine("Listening on port 1234.在浏览器中打开http://localhost:1234 ");
                Console.WriteLine("测试连接");
                Console.WriteLine();
                GetResponseAsync("http://localhost:1234").GetAwaiter().GetResult();
    
                Console.WriteLine();
                Console.WriteLine("输入回车键,停止服务");
                Console.ReadLine();
               string msg= server.Stop().GetAwaiter().GetResult();
                Console.WriteLine(msg);
                Console.Read();
            }
    
            static async Task GetResponseAsync(string url)
            {
    
                using (var client = new HttpClient())
                {
    
                    HttpResponseMessage responseMessage = await client.GetAsync(url);
                    string responseHeaders = responseMessage.Headers.ToString();
                    string response = await responseMessage.Content.ReadAsStringAsync();
                    Console.WriteLine("Response Headers:");
                    Console.WriteLine(responseHeaders);
                    Console.WriteLine("Response Body:");
                    Console.WriteLine(response);
    
                }
            }
    
        }
    
        class AsyncHttpServer
        {
            readonly HttpListener _listener;
            const string RESPONSE_TEMPLATE = "<html><head><title>Test</title></head>
    <body><h2>Test Page </h2><h4>ToDay is:{0}</h4></body></html>
    "; public AsyncHttpServer(int port) { _listener = new HttpListener(); _listener.Prefixes.Add(string.Format("http://+:{0}/", port)); } public async Task Start() { _listener.Start(); while (true) { var ctx = await _listener.GetContextAsync(); Console.WriteLine("{0} Client connected...",DateTime.Now.ToString()); string response = string.Format(RESPONSE_TEMPLATE, DateTime.Now); using (var sw = new StreamWriter(ctx.Response.OutputStream)) { await sw.WriteAsync(response); await sw.FlushAsync(); } } //return string.Format("监听服务开始 {0} ", DateTime.Now.ToString()); } public async Task<string> Stop() { _listener.Stop(); Console.WriteLine("监听停止,停止服务"); await Task.Delay(TimeSpan.FromSeconds(2)); return string.Format("监听服务停止 {0} ",DateTime.Now.ToString()); } } }

    2.http服务启动如下图。

     

    3.在浏览器中输入http://localhost:1234,之后如下图1。在等30秒之后,再次刷新,如下图中的2.

     

    4.在http的web服务程序中可以看到浏览器访问了服务器两次。如下图中的红框。

     

     4.在http的web服务程序中输入回车,则服务会停止 。如下图中的红框。

     

     

           这里我们通过HTTPListener类实现了一个非常简单的WEB服务器。也使用了TCPLISTENER类进行TCP套接字I/O操作。我们配置了监听器接收任何主机到本地机器1234端口的连接。然后在单独的工作线程中启动这个监管器,从而在主线程中可以控制这个监听器。

          当使用GetContextAsync方法时会发生异步I/O操作。可惜的是,其并不接收CancellationToken从而实现取消功能。所以如果想关闭这个服务器,只需要调用 _listenter.Abort方法,这将丢弃所有连接并关闭服务器。

           为了对这个服务器执行一个异步请求,我们使用了统一命名空间下的System.Net.Http集合中的HttpClient类。我们使用Get.Async方法来发起一个异步的Http Get请求。还有其他的方法用于发起其他的HTTP请求,比如POST,DELETE,PUT。HttpClient还有很多其他的选项,比如使用不同的格式(比如XML和JSON)来序列化和反序列化对象,指定代理服务器地址,认证以及其他配置。

           当运行这个程序时,可以看到这个服务器被启动起来。在服务器端代码中,我们使用GetContextAsync方法来接收新的客户端连接。当有新的客户端连接时这个方法就会返回。我们简单的输出一个包含当前日期和时间的非常基础的HTML作为响应。然后我们请求服务并打印响应头和内容。

     

  • 相关阅读:
    一步步学习微软InfoPath2010和SP2010--第十一章节--创建批准流程(7)--approval节
    一步步学习微软InfoPath2010和SP2010--第十一章节--创建批准流程(6)--表单加载规则
    一步步学习微软InfoPath2010和SP2010--第十一章节--创建批准流程(5)--状态域
    一步步学习微软InfoPath2010和SP2010--第十一章节--创建批准流程(4)--审批域
    一步步学习微软InfoPath2010和SP2010--第十一章节--创建批准流程(3)--表单视图
    SharePoint Designer 2010 安装教程
    解耦合是架构可伸缩的必要前提
    如何使用新东西
    学习开源组件之前先有平台或者先有环境再说
    沟通的技巧
  • 原文地址:https://www.cnblogs.com/chillsrc/p/8431311.html
Copyright © 2011-2022 走看看