【C#】一个简单的http服务器项目开发过程详解

这跟安装NoteJs程序运行脚本文件搭建一个简单Http服务器一样,相比起来,它的优点是可以开发的应用是免安装,跨平台的,放在移动盘上便捷的,这里着重讲http服务器实现的过程,以便自主实现特定的功能和服务。

打开Visual Studio开发工具,创建一个项目,

注意,项目开发语言是C#,使用的Net framework 4+ 框架,

创建的项目可以是以下三种

  • Console 控制台
  • WinForm 桌面程序
  • WPF 桌面程序

新建项目

这里以最简单的Console控制台项目开发为例,

新建项目,选一个项目来创建:控制台应用(.NET Framework),如下图

在这里插入图片描述

编写代码

创建好一个项目后,在第一个代码Program.cs文件中,

获取本机IP

添加如下代码如下,先获取本机的IP列表

using System.Net;namespace ConsoleApp1
{class Program{static void Main(string[] args){var IPs = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && ip.ToString().EndsWith(".1") != true).Select(ip => ip.ToString()).ToList();//...}}
}

继续写,获取第一个IP

var IP = IPs.FirstOrDefault();

启用HTTP服务

接下来,实现一个Http服务器

var server = new HttpListener();
var url = $"http://{IP}:8080/";
server.Prefixes.Add(url);
server.Start();
Console.WriteLine("Http服务器已开启,用浏览器访问:" + url);

从上面代码中可看出,先传入IP和端口号,就可开启一个Http服务

被拒绝访问

可以试着编译运行看,能否正常运行,

此时运行可会出现一个错误提示:拒绝访问!

这就是触及到网络安全和权限问题了,有三种解决方案:

解决方案一

将IP换成’127.0.0.1’

缺点:只能本机访问

解决方案二

以管理员身份运行程序

缺点:每次运行前都要授权:确认以管理员身份

解决方案三

在访问控制规则中设置,

以管理员身份运行Shell终端(CMD),执行一条命令如下:

netsh http add urlacl url=http://{ip}:{port}/ user=Everyone

其中{ip}:{port} 换成自己的IP和端口号

这样,下次运行程序就不会再次弹出拒绝访问问题,

若想恢复,就执行一条命令,如下:

netsh http delete urlacl url=http://{ip}:{port}/

访问首页

那http服务器顺利开启后,

若要访问页面,那是看不到什么页面内容的,

处理请求

需要自己实现,添加一行代码如下

server.BeginGetContext((ar) => OnResult(server, ar), null);

从上面代码看,当请求访问它的时候,会调用那一个方法OnResult

实现那个方法OnResult,代码如下

private static void OnResult(HttpListener server, IAsyncResult ar)
{if (!server.IsListening) return;var context = server.EndGetContext(ar);var request = context.Request;var response = context.Response;var method = request.HttpMethod.ToUpper();//...待实现if (server.IsListening) server.BeginGetContext((ar2)=>OnResult(server, ar2), null);
}

从上面代码看,对写过后端服务代码的同学来说,就会觉得这很像服务器处理请求业务的逻辑

  • request 是处理请求的对象
  • response 是响应输出的对象
  • method 是请求方法

在待实现那里,继续添加代码,

先判断请求地址,添加代码如下

var absUrl = HttpUtility.UrlDecode(request.Url.AbsolutePath);//request.RawUrl
if (absUrl=="/" || absUrl=="/index.html"){//...
}

从上面代码看,判断到地址是请求加载首页的话,就去加载首页文件

加载文件

把写好的网页文件index.html放到运行程序文件对应的文件夹wwwroot下,

然后实现,读取本地文件内容,代码如下

var filePath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "index.html");
var contents = System.IO.File.ReadAllText(filePath);
//...

响应内容

读取到内容,将输出给浏览器,代码如下

response.ContentType = "text/html;charset=UTF-8";
response.AddHeader("Content-Type", "text/html");
using (var writer = new System.IO.StreamWriter(response.OutputStream))
{writer.Write(contents);
}

其中text/html,是表示文件内容类型,

注意,以上响应输出方法只能处理符合条件text/*内容类型的文件,

其它文件类型的文件,需要另外的方法来实现处理请求响应,

输出完成后,记得执行如下代码,关闭响应

response.Close();

内容类型

网页文件中还有加载的资源文件是比较常见的,它们的内容类型不一样,如下表:

名称文件后缀名内容类型
文本.txttext/plain
网页.htmltext/html
网页.htmtext/html
样式.csstext/css
数据.jsonapplication/json
脚本.jsapplication/x-javascript
字体.ttfapplication/x-font-ttf
图标.icoimage/x-icon
图片.jpgimage/jpeg
图片.jpegimage/jpeg

更多文件内容类型,这里就不多列举了,如有需要请自行搜索

访问请求数据

当浏览器访问网页后,网页中有个资源标签需要加载服务器资源文件,还有网页脚本会请求访问服务器的数据,

所有加载资源的请求方法通常是GET,

判断请求方法

在之前的请求处理中,通过以下代码能判断

var method = request.HttpMethod.ToUpper();
if (method=="GET") {//...
} else if (method=="POST") {//...
}

处理GET请求

其中GET请求这里就不展开讲,这实现很简单吧,之前将加载网页文件就是处理GET请求来的,

有的请求地址中会带上查询数据,同如下这样

http://…com/q?csdn=zs1028

可判断请求地址中的查询部分,代码如下

var query = request.QueryString;
//...

判断请求地址里的查询数据,再处理不同的请求响应

处理POST请求

是POST请求的话,通常会发来表单数据,

在请求处理中可以读取表单数据,代码如下:

// 检查是否为 multipart/form-data
if (!request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase))
{throw new Exception("Only multipart/form-data is supported");
}var parser = new MultipartFormDataParser(request.InputStream);
//...

其中HttpMultipartParser是使用Nuget包管理器安装的,当时是 2.1.7版本,
表单数据就在parser对象里,看里面有什么属性,
例如,前端页面操作上传的文件,在请求处理中可从parser对象的属性Files获取

处理请求响应

处理完请求后,需要响应数据,

如果是返回文本内容,就执行以下代码

response.AddHeader("Content-Type", "text/plain");var contents = "ok";
using (var writer = new System.IO.StreamWriter(response.OutputStream))
{writer.Write(contents);
}

如果返回JSON内容,就执行以下代码

var result = new { code = 0, errMsg = "ok" };
response.AddHeader("Content-Type", "application/json");
var contents = new JavaScriptSerializer().Serialize(result);
using (var writer = new System.IO.StreamWriter(response.OutputStream))
{writer.Write(contents);
}

从代码中看出,result就是object对象类型,可以转换成json序列化数据

写到这里,基本上就可以编译运行测试了,

一个简单HTTP服务器就这样实现处理,是不是感觉很容易,它的应用场景可以多了,请自由想象!

对前端开发来说,可以把前端项目生成的网页打包进一个程序中,轻松部署,再加上浏览器运行组件那就是跨平台的程序。

就写到这里,( _ )/~~拜拜
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83120.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF【11_4】WPF实战-重构与美化(MVVM 架构)

11-9 【理论】MVVM 架构 在 WPF 项目中,我们主要采用的是一种类似 MVC 的架构,叫做 MVVM。 MVVM 继承了 MVC 的理念,是 Model-View-ViewModel 的缩写,中文意思是模型、视图、视图模型。这三个词分开看我们都能看懂,不…

使用PowerBI个人网关定时刷新数据

使用PowerBI个人网关定时刷新数据 PowerBI desktop连接mysql,可以设置定时刷新数据或在PowerBI服务中手动刷新数据,步骤如下: 第一步: 下载网关。以个人网关为例,如图 第二步: 双击网关,点击下一步&…

深度学习驱动的超高清图修复技术——综述

Deep Learning-Driven Ultra-High-Definition Image Restoration: A Survey Liyan Wang, Weixiang Zhou, Cong Wang, Kin-Man Lam, Zhixun Su, Jinshan Pan Abstract Ultra-high-definition (UHD) image restoration​​ aims to specifically solve the problem of ​​quali…

3 分钟学会使用 Puppeteer 将 HTML 转 PDF

需求背景 1、网页存档与文档管理 需要将网页内容长期保存或归档为PDF,确保内容不被篡改或丢失,适用于法律文档、合同、技术文档等场景。PDF格式便于存储和检索。 2、电子报告生成 动态生成的HTML内容(如数据分析报告、仪表盘)需导出为PDF供下载或打印。PDF保留排版和样…

电子邮箱设置SSL:构建邮件传输的加密护城河

在数字化通信高度依赖的今天,电子邮件作为企业协作与个人隐私的核心载体,其安全性直接关系到数据主权与商业利益。SSL(Secure Sockets Layer)作为网络通信加密的基石技术,通过为邮件传输建立加密隧道,有效抵…

Qt -使用OpenCV得到SDF

博客主页:【夜泉_ly】 本文专栏:【暂无】 欢迎点赞👍收藏⭐关注❤️ 目录 cv::MatdistanceTransform获得SDF 本文的目标, 是简单学习并使用OpenCV的相关函数, 并获得QImage的SDF(Signed Distance Field 有向距离场) 至…

Compose仿微信底部导航栏NavigationBar :底部导航控制滑动并移动

文章目录 1、准备工作1.1 参考1.2 依赖添加:1.3 主要控件NavigationBarHorizontalPager、VerticalPager 2、功能描述:3、实现过程3.1 创建一个数据类3.2 创建一个list变量3.3 具体实现3.3.1 创建共享的Pager状态3.3.2 将页面索引与页面标题同步3.3.3 创建…

WindowServer2022下docker方式安装dify步骤

WindowServer2022下docker方式安装dify步骤(稳定后考虑部署至linux中) 教程:https://blog.csdn.net/qq_49035156/article/details/143264534 0、资源要求 ---windows:8核CPU、16G内存、200G500G存储 ---10.21.31.122/administra…

【数据治理】要点整理-信息技术数据质量评价指标-GB/T36344-2018

导读:指标为数据质量评估提供了一套系统化、标准化的框架,涵盖规范性、完整性、准确性、一致性、时效性、可访问性六大核心指标,助力组织提升数据处理效率、支持决策制定及业务流程优化,确保数据在数据生存周期各阶段的质量可控。…

前端实现图片压缩:基于 HTML5 File API 与 Canvas 的完整方案

在 Web 开发中,处理用户上传的图片时,前端压缩可以有效减少服务器压力并提升上传效率。本文将详细讲解如何通过<input type="file">实现图片上传,结合 Canvas 实现图片压缩,并实时展示压缩前后的图片预览和文件大小对比。 一、核心功能架构 我们将实现以…

通信算法之280:无人机侦测模块知识框架思维导图

1. 无人机侦测模块知识框架思维导图, 见文末章节。 2. OFDM参数估计,基于循环自相关特性。 3. 无人机其它参数估计

单片机寄存器的四种主要类型!

1. 控制寄存器&#xff08;Control Registers&#xff09;​​ ​​专业定义​​&#xff1a;用于配置硬件行为或触发操作的寄存器。 ​​大白话​​&#xff1a; 相当于设备的​​“控制面板”​​&#xff0c;通过写入特定值来​​开关功能​​或​​调整参数​​。例如&am…

第100+41步 ChatGPT学习:R语言实现误判病例分析

本期是《第33步 机器学习分类实战&#xff1a;误判病例分析》的R版本。 尝试使用Deepseek-R1来试试写代码&#xff0c;效果还不错。 下面上R语言代码&#xff0c;以Xgboost为例&#xff1a; # 加载必要的库 library(caret) library(pROC) library(ggplot2) library(xgboost)…

HTML Day04

Day04 0.引言1. HTML字符实体2. HTML表单2.1 表单标签2.2 表单示例 3. HTML框架4. HTML颜色4.1 16进制表示法4.2 rgba表示法4.3 名称表达法 5. HTML脚本 0.引言 刚刚回顾了前面几篇博客&#xff0c;感觉写的内容倒是很详细&#xff0c;每个知识点都做了说明。但是感觉在知识组织…

comfyui 工作流中 视频长度和哪些参数有关? 生成15秒的视频,再加上RTX4060 8G显卡,尝试一下

想再消费级显卡上生成15秒长视频&#xff0c;还是比较慢的&#xff0c;不过动漫的画质要求比较低 在ComfyUI中生成15秒视频需综合考虑视频参数配置、模型选择和硬件优化&#xff0c;尤其针对RTX 4060 8G显存的限制。 ⏱️ 一、影响视频长度的核心参数 总帧数&#xff08;video_…

Netty 实战篇:构建高性能聊天服务器

在前两篇文章中&#xff0c;我们深入探讨了 Netty 的 IO 模型以及其核心组件的工作原理。本篇文章将通过一个实际的聊天服务器示例&#xff0c;展示如何使用 Netty 构建高性能的网络应用。 一、项目结构 项目主要包含以下几个部分&#xff1a; ChatServer&#xff1a;服务器启…

智绅科技——科技赋能健康养老,构建智慧晚年新生态

当老龄化浪潮与数字技术深度碰撞&#xff0c;智绅科技以 “科技赋能健康&#xff0c;智慧守护晚年” 为核心理念&#xff0c;锚定数字健康与养老服务赛道&#xff0c;通过人工智能、物联网、大数据等技术集成&#xff0c;为亚健康群体与中老年人群构建 “监测 - 预防 - 辅助 - …

Tkinter软件——显示txt标签的目标水平边框图像

代码&#xff1a; import tkinter as tk from tkinter import filedialog from tkinter import messagebox import cv2 from PIL import Image, ImageTk import osclass ImageBoxApp:def __init__(self, master):self.master masterself.master.title("Image Box Drawer…

Linux 文件覆盖机制与实践:以 mv 命令为切入点

引言&#xff1a;文件覆盖的本质 文件覆盖是 Linux 文件系统中常见的操作&#xff0c;指的是在目标路径已存在文件的情况下&#xff0c;将源文件的内容写入目标文件&#xff0c;导致目标文件的原有内容被替换。在 Linux 中&#xff0c;文件覆盖通常通过命令行工具&#xff08;…

学习路之PHP--easyswoole操作数据库

学习路之PHP--easyswoole操作数据库 0、安装orm插件一、创建数据库二、创建模型三、控制器显示四、效果五、问题 0、安装orm插件 composer require easyswoole/orm一、创建数据库 表&#xff1a; CREATE TABLE cases (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,titl…