多线程编程学习笔记——编写一个异步的HTTP服务器和客户端
二、 编写一个异步的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服务器和客户端的更多相关文章
- 多线程编程学习笔记——异步调用WCF服务
接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...
- 多线程编程学习笔记——async和await(一)
接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...
- 多线程编程学习笔记——使用异步IO(一)
接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...
- 多线程编程学习笔记——使用异步IO
接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...
- 多线程编程学习笔记——async和await(二)
接上文 多线程编程学习笔记——async和await(一) 三. 对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...
- 多线程编程学习笔记——async和await(三)
接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五. 处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...
- Java多线程编程(学习笔记)
一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过 ...
- [Java123] JDBC and Multi-Threading 多线程编程学习笔记
项目实际需求:DB交互使用多线程实现 多线程编程基础:1.5 :( (假设总分10) 计划一个半月从头学习梳理Java多线程编程基础以及Oracle数据库交互相关的多线程实现 学习如何通过代码去验证 ...
- Python3 多线程编程 - 学习笔记
线程 什么是线程 特点 线程与进程的关系 Python3中的多线程 全局解释器锁(GIL) GIL是啥? GIL对Python程序有啥影响? 改善GIL产生的问题 Python3关于多线程的模块 多线 ...
随机推荐
- 让两个数x,y一直保持互质的模版
int gcd(int x,int y) { )return x; else return gcd(y,x%y); }
- bzoj:1656 [Usaco2006 Jan] The Grove 树木
Description The pasture contains a small, contiguous grove of trees that has no 'holes' in the middl ...
- HDU 1017 A Mathematical Curiosity【水,坑】
A Mathematical Curiosity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- 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 ...
- linux下各文件夹的结构说明及用途介绍
linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令. /dev:设备特殊文件. /etc:系统管理和配置文件. /etc/rc.d:启动的配 置文件和脚本. /ho ...
- Oracle实战笔记(第三天)
导读 今天的主要内容有:java连接Oracle.事务.Oracle中的事务处理.Oracle函数. 一.Java连接Oracle的两种方式 第一种:桥连接(JDBC_ODBC)(不推荐) 1.准备工 ...
- Git分支管理及常见操作
众所周知,使用Git分支,我们可以从开发主线上分离开来,然后在不影响主线的同时继续工作. 既然要使用Git分支,这里就涉及到Git分支的管理及常见操作,如列出分支,分支的创建,分支的删除,分支的合并等 ...
- 织梦dedecsm系统"企业简介"类单栏目模版如何修改和调用
2013-1-12 14:46 | 发布者: moke | 栏目:dedecms教程 我们的模版里应该都有article_article.htm这个模版,这个模版是文章内容页模板,也就是 ...
- 网站地图怎么做?dedecms网站地图制作方法听语音
网站地图怎么生成?下面分享织梦dedecms系统网站地图的生成方式,怎么制作网站地图,方法很简单.下面介绍一下网站地图优化方法及制作方法. 工具/原料 一个网站 方法/步骤 第一步 登录网站后台 第二 ...
- 【笔记】css 实现宽度自适应屏幕 高度自适应宽度
如果说宽高自适应屏幕尺寸那么大家可能会想到 div{ width: 100%; height: 100% } 但是如果我要自适应屏幕尺寸的同时还要变成正方形呢?(高度和宽度相等而高度不能写死) 那就要 ...