接上文 多线程编程学习笔记——使用异步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: );
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());
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作为响应。然后我们请求服务并打印响应头和内容。

多线程编程学习笔记——编写一个异步的HTTP服务器和客户端的更多相关文章

  1. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

  2. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  3. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  4. 多线程编程学习笔记——使用异步IO

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  5. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

  6. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  7. Java多线程编程(学习笔记)

    一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过 ...

  8. [Java123] JDBC and Multi-Threading 多线程编程学习笔记

    项目实际需求:DB交互使用多线程实现 多线程编程基础:1.5  :( (假设总分10) 计划一个半月从头学习梳理Java多线程编程基础以及Oracle数据库交互相关的多线程实现 学习如何通过代码去验证 ...

  9. Python3 多线程编程 - 学习笔记

    线程 什么是线程 特点 线程与进程的关系 Python3中的多线程 全局解释器锁(GIL) GIL是啥? GIL对Python程序有啥影响? 改善GIL产生的问题 Python3关于多线程的模块 多线 ...

随机推荐

  1. Linux 下非root用户使用docker

    Linux 下非root用户使用docker 通常我们使用linux系统的时候,最好是不要直接使用root账号,但是使用Docker的时候,默认又是不能使用非root用户的,关于原因,官方说法如下: ...

  2. ubuntu下查看-卸载软件(卸载.net core sdk的方法)

    查看已安装的包:dpkg --list 查看正则匹配的包:dpkg --list 'dotnet-*' //查看以dotnet-开头的包 卸载匹配的包:sudo apt-get --purge rem ...

  3. CTF---隐写术入门第三题 打不开的文件

    打不开的文件分值:10 来源: 实验吧 难度:中 参与人数:2718人 Get Flag:1222人 答题人数:1276人 解题通过率:96% 咦!这个文件怎么打不开? 解题链接: http://ct ...

  4. 51 nod 1227 平均最小公倍数

    原题链接 Lcm(a,b)表示a和b的最小公倍数,A(n)表示Lcm(n,i)的平均数(1 <= i <= n), 例如:A(4) = (Lcm(1,4) + Lcm(2,4) + Lcm ...

  5. $(function(){...});的作用

    这是JQuery的语法,$表示JQuery对象,可以有好几种用法.比如传递选择器字符串.页面对象等,如果直接传函数体进去,表示网页加载完毕后要执行的意思.和JAVASCRIPT原来的这个是一样的: w ...

  6. c语言优化

    虽然对于优化C代码有很多有效的指导方针,但是对于彻底地了解编译器和你工作的机器依然无法取代,通常,加快程序的速度也会加大代码量.这些增加的代码也会影响一个程序的复杂度和可读性,这是不可接受的,比如你在 ...

  7. ip 淘宝ip库 精简版

    <?php header('Content-type: text/html; charset=utf-8'); //根据ip获取城市.网络运营商等信息 function findCityByIp ...

  8. async函数解析

    转载请注明出处:async函数解析 async函数是基于Generator函数实现的,也就是说是Generator函数的语法糖.在之前的文章有介绍过Generator函数语法和异步应用,如果对其不了解 ...

  9. IOS中UIScrollView的contentSize、contentOffset和contentInset属性

    IOS中,UIScrollView是可以滚动的视图,其中最常用的UITableView就是继承了UIScrollView. 跟所有的view一样,UIScrollView有一个frame属 性,同时, ...

  10. Code4 APP

    MJExtension 斯坦福大学公开课