接上文 多线程编程学习笔记——使用异步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. 让两个数x,y一直保持互质的模版

    int gcd(int x,int y) { )return x; else return gcd(y,x%y); }

  2. bzoj:1656 [Usaco2006 Jan] The Grove 树木

    Description The pasture contains a small, contiguous grove of trees that has no 'holes' in the middl ...

  3. HDU 1017 A Mathematical Curiosity【水,坑】

    A Mathematical Curiosity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  4. HDU 1004 Let the Balloon Rise【STL<map>】

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  5. linux下各文件夹的结构说明及用途介绍

    linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令.   /dev:设备特殊文件.   /etc:系统管理和配置文件.   /etc/rc.d:启动的配 置文件和脚本.   /ho ...

  6. Oracle实战笔记(第三天)

    导读 今天的主要内容有:java连接Oracle.事务.Oracle中的事务处理.Oracle函数. 一.Java连接Oracle的两种方式 第一种:桥连接(JDBC_ODBC)(不推荐) 1.准备工 ...

  7. Git分支管理及常见操作

    众所周知,使用Git分支,我们可以从开发主线上分离开来,然后在不影响主线的同时继续工作. 既然要使用Git分支,这里就涉及到Git分支的管理及常见操作,如列出分支,分支的创建,分支的删除,分支的合并等 ...

  8. 织梦dedecsm系统"企业简介"类单栏目模版如何修改和调用

    2013-1-12 14:46 | 发布者: moke | 栏目:dedecms教程        我们的模版里应该都有article_article.htm这个模版,这个模版是文章内容页模板,也就是 ...

  9. 网站地图怎么做?dedecms网站地图制作方法听语音

    网站地图怎么生成?下面分享织梦dedecms系统网站地图的生成方式,怎么制作网站地图,方法很简单.下面介绍一下网站地图优化方法及制作方法. 工具/原料 一个网站 方法/步骤 第一步 登录网站后台 第二 ...

  10. 【笔记】css 实现宽度自适应屏幕 高度自适应宽度

    如果说宽高自适应屏幕尺寸那么大家可能会想到 div{ width: 100%; height: 100% } 但是如果我要自适应屏幕尺寸的同时还要变成正方形呢?(高度和宽度相等而高度不能写死) 那就要 ...