当前位置: 首页 > news >正文

C#通讯——关于Winform中的简单的Http服务器与客户端

C#通讯——关于Winform中的简单的Http服务器与客户端

  • 前言
  • 一、Http是什么?
  • 二、简单的Http服务器
  • 三、简单的Http客户端
  • 四、实际调用
  • 五、Winform中Http服务器和WebApi的区别?


前言

在实际项目中通讯的交互的过程中,遇见数据传输时同事和我说用WebApi,Get,Post等等,以前没用搞过这个块的我傻傻分不清。查询资料了解过后发现只是个简单的Http交互通讯,在此记录下Winform中的简单服务器和客户端的编写,并简要描述webapi与http通讯的差异。


一、Http是什么?

HTTP(Hypertext Transfer Protocol)是一种用于在网络上传输超文本的协议。它是一个用于传输和交换超文本、图像、视频、音频以及其他多媒体资源的应用层协议。

HTTP是Web的基础,它定义了客户端和服务器之间的通信规则。通常,当你在浏览器中输入网址、点击链接或者提交表单时,浏览器会发送HTTP请求到服务器,服务器收到请求后进行处理,然后返回HTTP响应给客户端(浏览器),最终在你的浏览器上显示网页内容。

HTTP协议的主要特点包括:

  • 无状态性(Stateless):
    HTTP协议本身是无状态的,每个请求都是相互独立的,服务器并不会保留前后请求之间的状态信息。这导致每个请求都需要包含足够的信息来被服务器正确处理,比如会话标识或者其他验证信息。
  • 基于请求-响应模型:
    客户端发送请求给服务器,服务器处理请求并返回响应。这个请求-响应模型是HTTP的核心概念,通过这种方式客户端能够请求不同资源并且服务器能够提供响应。
  • 支持多种请求方法:
    HTTP定义了一系列请求方法(也称为HTTP谓词),包括GET(用于获取资源)、POST(用于提交数据给服务器)、PUT(用于更新资源)、DELETE(用于删除资源)等。
  • URL定位资源:
    每个HTTP请求都包含一个URL(Uniform Resource Locator),用于指定被请求的资源的位置。
  • 无连接性:
    HTTP协议本身是无连接的,即每次请求完成后,连接会立即关闭。这意味着每个请求都需要重新建立连接,可能会造成一定的性能开销。

二、简单的Http服务器

using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;namespace httpServer
{class HttpServer_DP{private readonly string mUrl; // 服务器监听的URLprivate readonly HttpListener mListener; // HttpListener实例private readonly Dictionary<string, Func<HttpListenerContext, Task<string>>> mRoutes; // 路由映射// 构造函数,接收服务器监听地址和端口的数组public HttpServer_DP(string[] prefixes){if (!HttpListener.IsSupported){throw new NotSupportedException("HttpListener is not supported on this platform.");}mListener = new HttpListener(); // 初始化HttpListener实例mRoutes = new Dictionary<string, Func<HttpListenerContext, Task<string>>>(); // 初始化路由映射字典// 为服务器添加监听地址和端口foreach (string prefix in prefixes){mListener.Prefixes.Add(prefix);}mUrl = prefixes[0]; // 记录第一个监听地址}public bool IsOpen { get { return mListener.IsListening; } }// 启动服务器public void Start(){mListener.Start();Console.WriteLine($"Server started and listening on {mUrl}");mListener.BeginGetContext(ProcessRequestCallback, mListener); // 处理客户端请求}// 停止服务器public void Stop(){mListener.Stop();mListener.Close();Console.WriteLine("Server stopped.");}// 添加路由和处理程序的映射关系public void AddRoute(string route, Func<HttpListenerContext, Task<string>> handler){mRoutes.Add(route, handler);}// 处理客户端请求的回调函数private async void ProcessRequestCallback(IAsyncResult result){HttpListener listener = (HttpListener)result.AsyncState;// 开始下一个请求的监听listener.BeginGetContext(ProcessRequestCallback, listener);try{// 获取传入的请求HttpListenerContext context = listener.EndGetContext(result);// 获取请求方法和URL路径string httpMethod = context.Request.HttpMethod;string responseString = "No Data!"; // 默认响应字符串string url = context.Request.Url.AbsolutePath;Func<HttpListenerContext, Task<string>> handler;// 如果请求路径存在于路由映射中,执行相应的处理程序if (mRoutes.TryGetValue(url, out handler)){responseString = await handler(context); // 获取处理程序返回的响应数据// 将响应数据编码成字节数组byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);// 设置响应的内容长度和状态码context.Response.ContentLength64 = buffer.Length;context.Response.StatusCode = (int)HttpStatusCode.OK;// 将响应写入输出流并关闭输出流context.Response.OutputStream.Write(buffer, 0, buffer.Length);context.Response.OutputStream.Close();}else{// 如果请求路径不存在于路由映射中,返回404 Not Foundcontext.Response.StatusCode = (int)HttpStatusCode.NotFound;context.Response.Close();}}catch (Exception ex){Console.WriteLine($"Error processing request: {ex.Message}");}}}
}

需要注意的是:Dictionary<string, Func<HttpListenerContext, Task>> mRoutes; // 路由映射
为了方便根据客户端传入的URL的不同路径来选择进行不同的处理流程

三、简单的Http客户端

using System;
using System.Net.Http;
using System.Threading.Tasks;namespace Http
{class HttpClient_DP{private readonly HttpClient _client; // HttpClient 实例// 构造函数,初始化 HttpClient 实例public HttpClient_DP(){_client = new HttpClient();}// 设置超时时间public TimeSpan TimeOut { set { _client.Timeout = value; } }// 发送 GET 请求并返回响应内容public async Task<string> Get(string url){HttpResponseMessage response = await _client.GetAsync(url); // 发送 GET 请求if (response.IsSuccessStatusCode){string content = await response.Content.ReadAsStringAsync(); // 读取响应内容return content;}else{return $"Error: {response.StatusCode}"; // 返回错误信息}}// 发送 POST 请求并返回响应内容public async Task<string> Post(string url, string data){HttpContent content = new StringContent(data); // 创建包含请求数据的 HttpContent 实例HttpResponseMessage response = await _client.PostAsync(url, content); // 发送 POST 请求if (response.IsSuccessStatusCode){string responseData = await response.Content.ReadAsStringAsync(); // 读取响应内容return responseData;}else{return $"Error: {response.StatusCode}"; // 返回错误信息}}}
}

其中只实现的Get与Post的相关代码,这也是当前我最常用的两个方法。
其中 public TimeSpan TimeOut为超时时间,不设置时将永久等待服务器响应。当响应超时时,外部可以通过(try-catch)捕获TaskCanceledException异常。

四、实际调用

初始化服务器:

        httpServer.HttpServer_DP HttpServer;public static void IniHttpServer(){HttpServer = new httpServer.HttpServer_DP(new string[]{"http://127.0.0.1:8080/"});//绑定映射,处理函数//当传入URL为"http://127.0.0.1:8080/PostAGVC_Data/"时将调用PostAGVC_Data函数接收和解析HttpServer.AddRoute("/PostAGVC_Data/", PostAGVC_Data);//当传入URL为"http://127.0.0.1:8080/PostAGV_Data/"时将调用PostAGV_Data函数接收和解析HttpServer.AddRoute("/PostAGV_Data/", PostAGV_Data);HttpServer.Start();}public static async Task<string> PostAGVC_Data(HttpListenerContext context){string httpMethod = context.Request.HttpMethod;string responseString = "";// 处理 POST 请求if (context.Request.HasEntityBody){// 从请求主体中获取数据using (System.IO.Stream body = context.Request.InputStream){using (System.IO.StreamReader reader = new System.IO.StreamReader(body, context.Request.ContentEncoding)){string postData = reader.ReadToEnd(); // 读取 POST 数据//处理数据//。。。。。。。。。。。。//。。。。。。。。。。。。//返回字符串responseString = "OK";}}}return responseString;}//与PostAGVC_Data内部类似,处理数据的代码不一样public static async Task<string> PostAGV_Data(HttpListenerContext context){//省略}

由于Http的无连接性,客户端只需要实例化后,需要时进行连接就行,简单的初始化(如果需要的话)如下:

		Http.HttpClient_DP HttpClient ;public static void IniHttpClient(){if (HttpClient == null){HttpClient = new Http.HttpClient_DP();HttpClient.TimeOut = TimeSpan.FromSeconds(10);}}

调用:
其中JsonConvert只是将我的类实例序列化成Json字符串,在此可以仅当字符串来看。

        string ret = await Global_Value.HttpClient.Post(url, JsonConvert.SerializeObject(new PLC_WorkState(){name = agvName,workState = workState}));

五、Winform中Http服务器和WebApi的区别?

在WinForms中编写的HTTP服务器类与WebAPI之间有几个主要区别:

1.目的和设计用途:

  • WinForms HTTP服务器类:
    通常是基于Socket或其他网络库手动实现的简单HTTP服务器。这样的服务器可能是为了特定目的而创建,比如在本地进行简单的通信或提供特定服务。
  • WebAPI: 是一个在Web开发中常用的框架,用于构建基于HTTP的RESTful
    API。它是ASP.NET框架的一部分,提供了更完整、功能更丰富的API开发环境,包括路由、中间件、控制器、模型绑定等。

2.功能和特性:

  • WinForms HTTP服务器类:
    往往具有较少的功能,可能只实现了基本的HTTP请求/响应处理,而缺少高级特性和工具。它通常用于较小规模的需求。
  • WebAPI:
    提供了许多功能强大的特性,例如路由,HTTP谓词(GET、POST、PUT等)的自动映射到相应的处理方法,参数绑定、模型验证等,使得开发者能够更轻松地构建和管理API。

3.集成和扩展性:

  • WinForms HTTP服务器类: 通常需要手动处理连接、请求、响应和其他网络层细节,灵活性较高,但也需要开发者自行处理许多功能。
  • WebAPI:
    集成在ASP.NET中,可以利用ASP.NET提供的丰富特性和中间件,容易与其他ASP.NET组件集成,并且具有更强的扩展性。

4.适用场景:

  • WinForms HTTP服务器类: 适用于需要在WinForms应用程序中实现简单的HTTP通信或提供基本服务的情况。

  • WebAPI: 更适合构建大型的Web应用程序或服务,提供多种HTTP服务,满足各种复杂的需求,例如构建RESTfulAPI供移动应用或Web前端使用。

总体来说,WinForms中的简单HTTP服务器类适用于简单的、局部的HTTP通信需求,而WebAPI更适用于构建和管理完整的Web服务或RESTful API,并提供了更多现成的工具和功能来简化开发流程。

相关文章:

C#通讯——关于Winform中的简单的Http服务器与客户端

C#通讯——关于Winform中的简单的Http服务器与客户端 前言一、Http是什么&#xff1f;二、简单的Http服务器三、简单的Http客户端四、实际调用五、Winform中Http服务器和WebApi的区别&#xff1f; 前言 在实际项目中通讯的交互的过程中&#xff0c;遇见数据传输时同事和我说用…...

Mendelson AS2 介绍下载和配置

最近与一家国外公司做EDI对接&#xff0c;并且EDI通讯工具是基于AS2协议的。目前开源的as2的开源项目有openas2,Mendelson AS2&#xff0c;和国人写的freeas2但是&#xff0c;现在freeas2已经被从开源中国不能下载了&#xff0c;变为收费的版本了。 如果你需要使用基于AS2协议…...

旅游海报图怎么做二维码展示?扫码即可查看图片

现在旅游攻略的海报可以做成二维码印刷在宣传单单页或者分享给用户来了解目的地的实际情况&#xff0c;出行路线、宣传海报等。用户只需要扫描二维码就可以查看内容&#xff0c;更加的方便省劲&#xff0c;那么旅游海报的图片二维码制作的技巧有哪些呢&#xff1f;使用图片二维…...

常用git指令

初始化Git仓库:git init 添加文件到暂存区:git add <file> 提交更改到本地仓库:git commit -m "commit message" 查看本地仓库的提交历史:git log 创建分支:git branch <branch_name> 切换分支:git checkout <branch_name> 查看所有分支:git…...

【FPGA】分享一些FPGA协同MATLAB开发的书籍

在做FPGA工程师的这些年&#xff0c;买过好多书&#xff0c;也看过好多书&#xff0c;分享一下。 后续会慢慢的补充书评。 【FPGA】分享一些FPGA入门学习的书籍【FPGA】分享一些FPGA协同MATLAB开发的书籍 【FPGA】分享一些FPGA视频图像处理相关的书籍 【FPGA】分享一些FPGA高速…...

幺模矩阵-线性规划的整数解特性

百度百科:幺模矩阵 在线性规划问题中&#xff0c;如果A为幺模矩阵&#xff0c;那么该问题具有最优整数解特性。也就是说使用单纯形法进行求解&#xff0c;得到的解即为整数解。无需再特定使用整数规划方法。 m i n c T x s . t . { A x ≥ b x ≥ 0 \begin{align*} min \quad…...

数据分析思维

Why&What 数据分析是为了驱动决策赋能业务。在数据分析过程中需要对目标进行拆解量化&#xff0c;如何拆解量化目标便是数据分析思维。 在任务拆解过程中使用的软件、统计模型、分析方法等为分析工具和手段&#xff0c;如何在恰当的场景合理的使用这些工具、模型、方法、手…...

C++ boost planner_cond_.wait(lock) 报错1225

1.如下程序段 boost unique_lock doesn’t own the mutex: Operation not permitted 问题&#xff1a; 其中makePlan是一个线程。这里的unlock导致错误这个报错 boost unique_lock doesn’t own the mutex: Operation not permitted bool navigation::makePlan(){ //cv::named…...

LeetCode刷题--- 字母大小写全排列

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述递归递归、搜索与回…...

165. 小猫爬山(DFS之剪枝与优化)

165. 小猫爬山 - AcWing题库 翰翰和达达饲养了 N 只小猫&#xff0c;这天&#xff0c;小猫们要去爬山。 经历了千辛万苦&#xff0c;小猫们终于爬上了山顶&#xff0c;但是疲倦的它们再也不想徒步走下山了&#xff08;呜咕>_<&#xff09;。 翰翰和达达只好花钱让它们…...

【Linux系统基础】(6)在Linux上大数据NoSQL数据库HBase集群部署、分布式内存计算Spark环境及Flink环境部署详细教程

大数据NoSQL数据库HBase集群部署 简介 HBase 是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。 和Redis一样&#xff0c;HBase是一款KeyValue型存储的数据库。 不过和Redis设计方向不同 Redis设计为少量数据&#xff0c;超快检索HBase设计为海量数据&#xff0c;…...

多维时序 | MATLAB实CNN-BiGRU-Mutilhead-Attention卷积网络结合双向门控循环单元网络融合多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现CNN-BiGRU-Mutilhead-Attention卷积网络结合双向门控循环单元网络融合多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现CNN-BiGRU-Mutilhead-Attention卷积网络结合双向门控循环单元网络融合多头注意力机制多变量时间序列预测预测效果基本介…...

vs快捷键

ctrlMo 折叠代码块 ctrlML 打开代码块...

linux 内核时间计量方法

定时器中断由系统定时硬件以规律地间隔产生; 这个间隔在启动时由内核根据 HZ 值来编 程, HZ 是一个体系依赖的值, 在 <linux/param.h>中定义或者它所包含的一个子平台文 件中. 在发布的内核源码中的缺省值在真实硬件上从 50 到 1200 嘀哒每秒, 在软件模拟 器中往下到 24.…...

循环神经网络中的梯度消失或梯度爆炸问题产生原因分析(二)

上一篇中讨论了一般性的原则&#xff0c;这里我们具体讨论通过时间反向传播&#xff08;backpropagation through time&#xff0c;BPTT&#xff09;的细节。我们将展示目标函数对于所有模型参数的梯度计算方法。 出于简单的目的&#xff0c;我们以一个没有偏置参数的循环神经…...

JWT signature does not match locally computed signature

1. 问题背景 最近在协助团队小盆友调试一个验签问题&#xff0c;结果还“节外生枝”了&#xff0c;原来不是签名过程的问题&#xff0c;是token的问题。 当你看到“JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not…...

vitepress项目使用github的action自动部署到github-pages中,理论上可以通用所有

使用github的action自动部署到github-pages中 创建部署的deploy.yml文件&#xff0c;在项目的根目录下面 .github\workflows\deploy.yml 完整的代码&#xff1a;使用的是pnpm进行依赖安装。 name: 部署VitePresson:push:branches:- docs # 这段是在推送到 docs 分支时触发该…...

Python爬虫---解析---JSONPath

Xpath可以解析本地文件和服务器响应的文件&#xff0c;JSONPath只能解析本地文件 1. 安装jsonpath&#xff1a;pip install jsonpath 注意&#xff1a;需要安装在python解释器相同的位置,例如&#xff1a;D:\Program Files\Python3.11.4\Scripts 2. 使用步骤 2.1 导入&…...

路由器介绍和命令操作

先来回顾一下上次的内容&#xff1a; ip地址就是由32位二进制数组 二进位数就是只有数字0和1组成 网络位&#xff1a;类似于区号&#xff0c;表示区域作用 主机位&#xff1a;类似于号码&#xff0c;表示区域中编号 网络名称&#xff1a;网络位不变&#xff0c;主机位全为0 …...

Hadoop——分布式计算

一、分布式计算概述 1. 什么是计算、分布式计算? 计算:对数据进行处理,使用统计分析等手段得到需要的结果分布式计算:多台服务器协同工作,共同完成一个计算任务2. 分布式计算常见的2种工作模式分散->汇总 (MapReduce就是这种模式)将数据分片,多台服务器各自负责一…...

学校AIGC检测标准差异解读:不同高校AI率标准对比2026年如何针对性免费处理完整指南

学校AIGC检测标准差异解读&#xff1a;不同高校AI率标准对比2026年如何针对性免费处理完整指南 同一段文字&#xff0c;不同平台检测AI率相差20%以上。这不是玄学&#xff0c;有原因可解释。 关于高校AIGC检测标准差异解读&#xff0c;理解了背后逻辑&#xff0c;很多「奇怪现…...

高性能系统发育计算库:BEAGLE 库完整安装与优化指南

高性能系统发育计算库&#xff1a;BEAGLE 库完整安装与优化指南 【免费下载链接】beagle-lib general purpose library for evaluating the likelihood of sequence evolution on trees 项目地址: https://gitcode.com/gh_mirrors/be/beagle-lib BEAGLE&#xff08;Broa…...

书匠策AI官网www.shujiangce.com:期刊论文从“渡劫“到“躺赢“,中间只差这一个工具

家人们&#xff0c;今天不讲课&#xff0c;今天带你们"开箱"一个我私藏很久的论文神器。 先说结论——书匠策AI&#xff08; 官网直达&#xff1a;www.shujiangce.com&#xff09; 的期刊论文功能&#xff0c;是我今年用过最"懂科研人"的AI工具&#xff…...

别再手动调参了!用Simulink系统辨识工具箱,5分钟搞定Buck电路的PID控制器设计

电力电子工程师的效率革命&#xff1a;用Simulink系统辨识工具箱5步完成Buck电路PID设计 在电力电子领域&#xff0c;Buck电路作为最基础的DC-DC降压拓扑&#xff0c;其控制器设计一直是工程师的必修课。传统的手工计算和试错调参方法不仅耗时费力&#xff0c;还难以达到理想的…...

不只是跑通:用D435i和VINS-Mono做个室内小车的视觉里程计demo

从D435i到移动机器人&#xff1a;VINS-Mono室内视觉里程计实战指南 当Intel RealSense D435i深度相机遇上VINS-Mono这个轻量级视觉惯性里程计框架&#xff0c;我们能在一台简易ROS小车上实现怎样的定位与建图效果&#xff1f;本文将带你从硬件连接开始&#xff0c;逐步完成传感…...

UE5保姆级教程:用Electra Player插件在场景里放视频,从导入MP4到带声音播放

UE5实战指南&#xff1a;Electra Player插件实现场景视频播放全流程解析 在虚幻引擎5的沉浸式场景中&#xff0c;视频播放功能已成为增强环境叙事的关键技术。无论是商场里的动态广告屏、科幻场景中的全息投影&#xff0c;还是角色手持设备的交互界面&#xff0c;流畅的视频播放…...

MicroG终极指南:3步解决华为设备Google服务依赖难题

MicroG终极指南&#xff1a;3步解决华为设备Google服务依赖难题 【免费下载链接】GmsCore Free implementation of Play Services 项目地址: https://gitcode.com/GitHub_Trending/gm/GmsCore 你是否曾为华为设备上无法正常使用Google服务而烦恼&#xff1f;想要享受完整…...

Android 显示框架:SurfaceFlinger与合成策略探析

1. SurfaceFlinger的核心角色解析 第一次拆解Android显示系统时&#xff0c;我被SurfaceFlinger这个名称逗笑了——"Surface抛洒者"&#xff1f;后来发现这个命名意外地准确。想象你正在布置多屏艺术展&#xff0c;SurfaceFlinger就是那个决定每幅画作展示位置、叠加…...

别再用docker tag了!深入理解Containerd生态:crictl、ctr与nerdctl到底该怎么选?

深入解析Containerd生态&#xff1a;crictl、ctr与nerdctl的镜像管理实战指南 在容器技术快速发展的今天&#xff0c;越来越多的开发者正从Docker生态转向Containerd这一更轻量、更符合Kubernetes标准的运行时环境。但当我们真正开始使用Containerd时&#xff0c;往往会遇到一个…...

3分钟搞定Figma中文界面:设计师必备的终极汉化方案

3分钟搞定Figma中文界面&#xff1a;设计师必备的终极汉化方案 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 面对Figma满屏的英文界面感到困扰吗&#xff1f;专业术语看不懂、操作按钮…...