利用C#中的HttpListener可以模拟web服务器接收web请求。
HttpListener说明:
提供一个简单的、可通过编程方式控制的 HTTP 协议侦听器
| 名称 | 说明 | |
|---|---|---|
| AuthenticationSchemes | 获取或设置用于客户端身份验证的方案。 | |
| AuthenticationSchemeSelectorDelegate | 获取或设置一个委托,调用它来确定用于客户端身份验证的协议。 | |
| DefaultServiceNames | 获取由已注册前缀确定的服务提供程序名 (SPN) 的默认列表。 | |
| ExtendedProtectionPolicy | 获取或设置用于会话的扩展保护的 ExtendedProtectionPolicy。 | |
| ExtendedProtectionSelectorDelegate | 获取或设置在确定要用于每个请求的 ExtendedProtectionPolicy 时调用的委托。 | |
| IgnoreWriteExceptions | 获取或设置 Boolean 值,该值指定应用程序是否接收 HttpListener 向客户端发送响应时发生的异常。 | |
| IsListening | 获取一个值,指示 HttpListener 是否已启动。 | |
![]() | IsSupported | 获取一个值,指示 HttpListener 是否可用于当前操作系统。 |
| Prefixes | 获取由此 HttpListener 对象处理的统一资源标识符 (URI) 前缀。 | |
| Realm | 获取或设置与此 HttpListener 对象关联的领域或资源分区。 | |
| TimeoutManager | 此 HttpListener 实例的超时管理器。 | |
| UnsafeConnectionNtlmAuthentication | 获取或设置 Boolean 值,该值控制当使用 NTLM 时是否需要对使用同一传输控制协议 (TCP) 连接的其他请求进行身份验证。 |
| 名称 | 说明 | |
|---|---|---|
| Abort() | 立刻关闭 HttpListener 对象,这样会放弃所有当前排队的请求。 | |
| BeginGetContext(AsyncCallback, Object) | 开始异步检索传入的请求。 | |
| Close() | 关闭 HttpListener。 | |
| EndGetContext(IAsyncResult) | 完成检索传入的客户端请求的异步操作。 | |
| Equals(Object) | 确定指定的对象是否等于当前对象。(继承自 Object。) | |
| GetContext() | 等待传入的请求,接收到请求时返回。 | |
| GetContextAsync() | 等待传入请求以作为异步操作。 | |
| GetHashCode() | 作为默认哈希函数。(继承自 Object。) | |
| GetType() | ||
| Start() | 允许此实例接收传入的请求。 | |
| Stop() | 使此实例停止接收传入的请求。 | |
| ToString() | 返回表示当前对象的字符串。(继承自 Object。) |
主要分为以下几步
1.创建一个HTTP侦听器对象并初始化
2.添加需要监听的URI 前缀
3.开始侦听来自客户端的请求
4.处理客户端的Http请求
5.关闭HTTP侦听器
主要核心代码:
public delegate void WndProcDelegater(ref Message m);
public class HttpServerBLL
{
public WndProcDelegater ServerWndProc;
public IVShow ivshow;
#region
public string Host { get; set; }
public string port { get; set; }
private string _webHomeDir = Application.StartupPath + "\\Web";
private HttpListener listener;
private Thread listenThread;
private string directorySeparatorChar = Path.DirectorySeparatorChar.ToString();
public string ImageUploadPath { get; set; }
/// <summary>
/// http服务根目录
/// </summary>
public string WebHomeDir
{
get { return this._webHomeDir; }
set
{
if (!Directory.Exists(value))
throw new Exception("http服务器设置的根目录不存在!");
this._webHomeDir = value;
}
}
/// <summary>
/// 服务器是否在运行
/// </summary>
public bool IsRunning
{
get { return (listener == null) ? false : listener.IsListening; }
}
#endregion
#region
public HttpServerBLL(string host, string port, string webHomeDir, string imageUploadPath)
{
this.Host = host;
this.port = port;
this._webHomeDir = webHomeDir;
ImageUploadPath = imageUploadPath;
listener = new HttpListener();
}
public bool AddPrefixes(string uriPrefix)
{
string uri = "http://" + uriPrefix + ":" + this.port + "/";
if (listener.Prefixes.Contains(uri)) return false;
listener.Prefixes.Add(uri);
return true;
}
/// <summary>
/// 启动服务
/// </summary>
public void Start()
{
try
{
if (listener.IsListening)
return;
listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; //// 匿名访问
if (!string.IsNullOrEmpty(Host) && Host.Length > 0)
{
var str = "http://" + Host + ":" + this.port + "/";
listener.Prefixes.Add(str);
}
else if (listener.Prefixes == null || listener.Prefixes.Count == 0)
{
var str = "http://localhost:" + this.port + "/";
listener.Prefixes.Add(str);
}
listener.Start();
//AcceptClient();
listenThread = new Thread(AcceptClient);
listenThread.IsBackground = true;
listenThread.Name = "httpserver";
listenThread.Start();
}
catch (Exception ex)
{
MessageBox.Show("启动失败");
}
}
/// <summary>
/// 停止服务
/// </summary>
public void Stop()
{
try
{
if (listener != null)
{
listener.Stop();
}
}
catch (Exception ex)
{
LogHelper.WriteLog(typeof(HttpServerBLL), ex);
}
}
/// <summary>
/// /接受客户端请求
/// </summary>
void AcceptClient()
{
while (listener.IsListening)
{
try
{
HttpListenerContext context = listener.GetContext();
//new Thread(HandleRequest).Start(context);
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context);
}
catch (Exception ex)
{
LogHelper.WriteLog(typeof(HttpServerBLL), ex);
}
}
}
#endregion
#region HandleRequest
//处理客户端请求
private void HandleRequest(object ctx)
{
HttpListenerContext context = ctx as HttpListenerContext;
HttpListenerResponse response = context.Response;
HttpListenerRequest request = context.Request;
response.Headers["Access-Control-Allow-Origin"] = "*";//避免跨域
try
{
string rawUrl = System.Web.HttpUtility.UrlDecode(request.RawUrl);
int paramStartIndex = rawUrl.IndexOf('?');
if (paramStartIndex > 0)
rawUrl = rawUrl.Substring(0, paramStartIndex);
else if (paramStartIndex == 0)
rawUrl = "";
if (string.Compare(rawUrl, "/ImageUpload", true) == 0)
{
ImageUploadExec(context);
}
else if (string.Compare(rawUrl, "/Message", true) == 0)
{
MessageExec(context);
}
else if (string.Compare(rawUrl, "/FileImage", true) == 0)
{
FileImageExec(context);
}
else
{
OtherExec(context, rawUrl);
}
}
catch (Exception ex)
{
LogHelper.WriteLog(typeof(HttpServerBLL), ex);
response.StatusCode = 200;
response.ContentType = "text/plain";
using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
{
writer.WriteLine("接收完成!");
}
}
try
{
response.Close();
}
catch (Exception ex)
{
LogHelper.WriteLog(typeof(HttpServerBLL), ex);
}
}
private void OtherExec(HttpListenerContext context, string rawUrl)
{
HttpListenerResponse response = context.Response;
HttpListenerRequest request = context.Request;
#region 网页请求
string InputStream = "";
using (var streamReader = new StreamReader(request.InputStream))
{
InputStream = streamReader.ReadToEnd();
}
string filePath = "";
if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/")
filePath = WebHomeDir + directorySeparatorChar + "Index.html";
else
filePath = WebHomeDir + rawUrl.Replace("/", directorySeparatorChar);
if (!File.Exists(filePath))
{
response.ContentLength64 = 0;
response.StatusCode = 404;
response.Abort();
}
else
{
response.StatusCode = 200;
string exeName = Path.GetExtension(filePath);
response.ContentType = GetContentType(exeName);
FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite);
int byteLength = (int)fileStream.Length;
byte[] fileBytes = new byte[byteLength];
fileStream.Read(fileBytes, 0, byteLength);
fileStream.Close();
fileStream.Dispose();
response.ContentLength64 = byteLength;
response.OutputStream.Write(fileBytes, 0, byteLength);
response.OutputStream.Close();
}
#endregion
}
private void FileImageExec(HttpListenerContext context)
{
HttpListenerResponse response = context.Response;
HttpListenerRequest request = context.Request;
var path = request.QueryString["Path"];
var dirPath = string.Format("{0}\\Image", Application.StartupPath);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
#region 网页请求
string filePath = string.Format("{0}\\{1}", Application.StartupPath, path);
if (!File.Exists(filePath))
{
response.ContentLength64 = 0;
response.StatusCode = 404;
response.Abort();
}
else
{
response.StatusCode = 200;
string exeName = Path.GetExtension(filePath);
response.ContentType = GetContentType(exeName);
FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite);
int byteLength = (int)fileStream.Length;
byte[] fileBytes = new byte[byteLength];
fileStream.Read(fileBytes, 0, byteLength);
fileStream.Close();
fileStream.Dispose();
response.ContentLength64 = byteLength;
response.OutputStream.Write(fileBytes, 0, byteLength);
response.OutputStream.Close();
}
#endregion
}
private void MessageExec(HttpListenerContext context)
{
HttpListenerResponse response = context.Response;
HttpListenerRequest request = context.Request;
if (ServerWndProc != null)
{
var w = request.QueryString["width"].ToInt();
var h = request.QueryString["height"].ToInt();
var t = request.QueryString["top"].ToInt();
var l = request.QueryString["left"].ToInt();
if (ivshow != null)
{
ivshow.ShowVideo(new Size(w, h), new System.Drawing.Point(t, l));
}
response.StatusCode = 200;
response.OutputStream.Close();
//var m=new Message{
//};
//ServerWndProc(ref m);
}
}
private void ImageUploadExec(HttpListenerContext context)
{
HttpListenerResponse response = context.Response;
HttpListenerRequest request = context.Request;
#region 上传图片
string fileName = context.Request.QueryString["name"];
string filePath = ImageUploadPath + "\\" + DateTime.Now.ToString("yyMMdd_HHmmss_ffff")
+ Path.GetExtension(fileName).ToLower();
using (var stream = request.InputStream)
{
using (var br = new BinaryReader(stream))
{
IOHelper.WriteStreamToFile(br, filePath, request.ContentLength64);
}
}
response.ContentType = "text/html;charset=utf-8";
using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
{
writer.WriteLine("接收完成!");
}
#endregion
}
#endregion
#region GetContentType
/// <summary>
/// 获取文件对应MIME类型
/// </summary>
/// <param name="fileExtention">文件扩展名,如.jpg</param>
/// <returns></returns>
protected string GetContentType(string fileExtention)
{
if (string.Compare(fileExtention, ".html", true) == 0
|| string.Compare(fileExtention, ".htm", true) == 0)
return "text/html;charset=utf-8";
else if (string.Compare(fileExtention, ".js", true) == 0)
return "application/javascript";
else if (string.Compare(fileExtention, ".css", true) == 0)
return "application/javascript";
else if (string.Compare(fileExtention, ".png", true) == 0)
return "image/png";
else if (string.Compare(fileExtention, ".jpg", true) == 0 || string.Compare(fileExtention, ".jpeg", true) == 0)
return "image/jpeg";
else if (string.Compare(fileExtention, ".gif", true) == 0)
return "image/gif";
else if (string.Compare(fileExtention, ".swf", true) == 0)
return "application/x-shockwave-flash";
else
return "";//application/octet-stream
}
#endregion
}