最近項目上遇到一個需求,最后想到的解決方案是自己實現一個web服務器去處理請求,然后再將信息發送到另外一個程序。然后返回處理之后的結果呈現出來。
現在我就來分享一下如何實現的。
通過.NET 為我們提供的HttpListener類實現對Http協議的處理,實現簡單的web服務器。
注意:此類在 .NET Framework 2.0 版中是新增的。所以支持.NET Framework 2.0以上版本。該類僅在運行 Windows XP SP2 或 Windows Server 2003 操作系統的計算機上可用。
引用命名空間:using System.Net;
使用Http服務一般步驟如下:
-
創建一個HTTP偵聽器對象並初始化
-
開始偵聽來自客戶端的請求
-
處理客戶端的Http請求
-
關閉HTTP偵聽器
創建一個HTTP偵聽器對象
創建HTTP偵聽器對象只需要新建一個HttpListener對象即可。
|
1
|
HttpListener listener =
new
HttpListener();
|
初始化需要經過如下兩步
- 添加需要監聽的URL范圍至listener.Prefixes中,可以通過如下函數實現:
多個的話可以采用循環添加。1 - 調用listener.Start()實現端口的綁定,並開始監聽客戶端的需求。
偵聽來自客戶端的請求
這里有2種方式可以偵聽HTTP請求,獲取HttpListenerContext的最簡單方式如下:
|
1
|
HttpListenerContext context = listener.GetContext();
|
該方法將阻塞調用函數至接收到一個客戶端請求為止,如果要提高響應速度,可使用異步方法listener.BeginGetContext()來實現HttpListenerContext對象的獲取。
我使用的是異步方式實現對HttpListenerContext對象的獲取。
處理客戶端的HTTP請求
獲取HttpListenerContext后,可通過Request屬性獲取表示客戶端請求的對象,通過Response屬性取表示 HttpListener 將要發送到客戶端的響應的對象。
|
1
2
|
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
|
關閉HTTP偵聽器
通過調用listener.Stop()函數即可關閉偵聽器,並釋放相關資源
實現GET POST請求處理
GET請求比較簡單,直接通過 request.QueryString["linezero"]; QueryString就可以實現獲取參數。
POST請求由於HttpListener 不提供實現,需要自己做處理。在下面相關代碼中會貼出方法。
相關代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace WebConsole
{
class Program
{
static HttpListener sSocket;
static void Main(string[] args)
{
sSocket = new HttpListener();
sSocket.Prefixes.Add("http://127.0.0.1:8080/");
sSocket.Start();
sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);
Console.WriteLine("已啟動監聽,訪問http://127.0.0.1:8080/");
Console.ReadKey();
}
static void GetContextCallBack(IAsyncResult ar)
{
try
{
sSocket = ar.AsyncState as HttpListener;
HttpListenerContext context = sSocket.EndGetContext(ar);
//再次監聽請求
sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);
//處理請求
string a = Request(context.Request);
//輸出請求
Response(context.Response, a);
}
catch { }
}
/// <summary>
/// 處理輸入參數
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
static string Request(HttpListenerRequest request)
{
string temp = "welcome to linezero!";
if (request.HttpMethod.ToLower().Equals("get"))
{
//GET請求處理
if (!string.IsNullOrEmpty(request.QueryString["linezero"]))
temp = request.QueryString["linezero"];
}
else if (request.HttpMethod.ToLower().Equals("post"))
{
//這是在POST請求時必須傳參的判斷默認注釋掉
//if (!request.HasEntityBody)
//{
// temp = "請傳入參數";
// return temp;
//}
//POST請求處理
Stream SourceStream = request.InputStream;
byte[] currentChunk = ReadLineAsBytes(SourceStream);
//獲取數據中有空白符需要去掉,輸出的就是post請求的參數字符串 如:username=linezero
temp = Encoding.Default.GetString(currentChunk).Replace("", "");
}
return temp;
}
static byte[] ReadLineAsBytes(Stream SourceStream)
{
var resultStream = new MemoryStream();
while (true)
{
int data = SourceStream.ReadByte();
resultStream.WriteByte((byte)data);
if (data <= 10)
break;
}
resultStream.Position = 0;
byte[] dataBytes = new byte[resultStream.Length];
resultStream.Read(dataBytes, 0, dataBytes.Length);
return dataBytes;
}
/// <summary>
/// 輸出方法
/// </summary>
/// <param name="response">response對象</param>
/// <param name="responseString">輸出值</param>
/// <param name="contenttype">輸出類型默認為json</param>
static void Response(HttpListenerResponse response, string responsestring, string contenttype = "application/json")
{
response.StatusCode = 200;
response.ContentType = contenttype;
response.ContentEncoding = Encoding.UTF8;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responsestring);
//對客戶端輸出相應信息.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
//關閉輸出流,釋放相應資源
output.Close();
}
}
}
最后啟動程序,在地址欄里輸入http://127.0.0.1:8080 就可以訪問了。

