C# 多线程 09-使用异步 I/O 02-编写一个异步的 HTTP 服务器和客户端
🏷️ 《C# 多线程》
示例代码
csharp
/// <summary>
/// 编写一个异步的 HTTP 服务器和客户端
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
var server = new AsyncHttpServer(1234);
var t = Task.Run(() => server.Start());
Console.WriteLine("Listening on port 1234. Opent http://localhost:1234 iin your browser.");
Console.WriteLine("Trying to conect:");
Console.WriteLine();
GetResponseAsync("http://localhost:1234").GetAwaiter().GetResult();
Console.WriteLine();
Console.WriteLine("Press Enter to stop the server");
Console.ReadLine();
server.Stop().GetAwaiter().GetResult();
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
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
{
// 使用 HttpListener 实现一个简单的服务器
readonly HttpListener _listener;
const string RESPONSE_TEMPLATE = "<html><head><title>Test</title></head><body><h2>Testpage</h2><h4>Today is: {0}</h4></body></html>";
public AsyncHttpServer(int portNumber)
{
_listener = new HttpListener();
_listener.Prefixes.Add($"http://localhost:{portNumber}/");
}
public async Task Start()
{
// 启动服务器
_listener.Start();
while (true)
{
// 调用 GetContextAsync 会发生异步 I/O 操作
var ctx = await _listener.GetContextAsync();
// 接收到请求时继续下面的处理
Console.WriteLine("Client connected...");
// 返回一个简单的 HTML 页面
var response = string.Format(RESPONSE_TEMPLATE, DateTime.Now);
using (var sw = new StreamWriter(ctx.Response.OutputStream))
{
await sw.WriteAsync(response);
await sw.FlushAsync();
}
}
}
public async Task Stop()
{
// 调用 Abort 方法丢弃所有连接并关闭服务器
_listener.Abort();
}
}
运行结果
txt
Listening on port 1234. Opent http://localhost:1234 iin your browser.
Trying to conect:
Client connected...
Response headers:
Transfer-Encoding: chunked
Date: Mon, 28 Aug 2017 08:38:11 GMT
Server: Microsoft-HTTPAPI/2.0
Response body:
<html><head><title>Test</title></head><body><h2>Testpage</h2><h4>Today is: 2017/
8/28 16:38:11</h4></body></html>
Press Enter to stop the server
Client connected...
Client connected...
Press Enter to exit