各位朋友大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是http://qinyuanpei.com。在我们这个Web服务器有了1个基本的门面以后,我们是时候来用它做点实际的事情了。还记得我们最早提到HTTP协议的用处是甚么吗?它叫超文本传输协议啊,所以我们必须斟酌让我们的服务器能够接收到客户端传来的数据。由于我们目前完成了大部份的工作,所以对数据传输这个问题我们这里选择以最简单的GET和POST为例来实现,这样我们今天的重点就落实在Get和Post的实现这个问题上来。而从原理上来说,不管Get方式要求还是Post方式要求,我们都可以在要求报文中取得其要求参数,不同的是前者出现在要求行中,而后者出现在消息体中。例如我们传递的两个参数num1和num2对应的数值分别是12和24,那末在具体的要求报文中我们都能找到类似“num1=12&num2=24”这样的字符结构,所以只要针对这个字符结构进行解析,就能够取得客户端传递给服务器的参数啦。

实现Get要求

首先我们来实现Get要求,Get是HTTP协议中默许的要求类型,我们平时访问网页、要求资源实际上都是通过Get方式实现的。Get方式要求需要通过类似“?id=001&option=10”这样的情势附加在URL上,因此Get方式对阅读器来讲是透明的,即用户可以通过阅读器地址栏知道,这个进程中传递了哪些参数和这些参数的值分别是甚么。而由于阅读器的限制,我们通过这类方式要求的时候能够传递的参数数目和长度都是有限的,而且当参数中存在中文数值的时候还需要对其进行编码。Get方式要求相对简单,我们下面来看看它的要求报文:

GET /?num1=23&num2=12 HTTP/1.1

Accept: text/html, application/xhtml+xml, image/jxr, */*

Accept-Language: zh-Hans-CN,zh-Hans;q=0.5

User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586

Accept-Encoding: gzip, deflate

Host: localhost:4040

Connection: Keep-Alive

Cookie: _ga=GA1.1.1181222800.1463541781

此时我们可以注意到在要求报文第1行,即要求行中出现了“/?num1=23&num2=12”这样的字样,这就是客户端传递给服务器的参数,我们很容易想到只需要将这个字段串中的“键”和“值”都解析出来,服务器就能够对这些数据进行处理然后返回给客户端了。所以下面我们通过这样的方式来实现,我们为HtttpRequest类增加了1个Parms属性,它是1个键和值均为字符串类型的字典,我们使用这个字典来存储和管理客户端传递来的参数。

//获得要求参数

if(this.Method == "GET" && this.URL.Contains('?'))

this.Params = GetRequestParams(lines[0].Split(' ')[1].Split('?')[1]);

明显我们首先需要判断要求类型是不是为GET和要求中是不是带有参数,其方法是判断要求地址中是不是含有“?”字符。这里的lines是指将报文信息按行分割以后的数组,明显要求地址在第1行,所以我们根据“?”分割该行数据以后就能够得到“num1=23&num2=12”这样的结果,这里我们使用1个方法GetRequestParms来返回参数字典,这样作做是为了复用方法,由于在处理Post要求的时候我们会继续使用这个方法。该方法定义以下:

///

/// 从内容中解析要求参数并返回1个字典

///

/// 使用&连接的参数字符串

/// 如果存在参数则返回参数否则返回null

protected Dictionary GetRequestParams(string content)

{

//防御编程

if(string.IsNullOrEmpty(content))

return null;

//依照&对字符进行分割

string[] reval = content.Split('&');

if(reval.Length <= 0)

return null;

//将结果添加至字典

Dictionary dict = new Dictionary();

foreach(string val in reval)

{

string[] kv = val.Split('=');

if(kv.Length <= 1)

dict.Add(kv[0], "");

dict.Add(kv[0],kv[1]);

}

//返回字典

return dict;

}

实现Post要求

Post要求相对Get要求比较安全,由于它克服了Get要求参数长度的限制问题,而且由于它的参数是寄存在消息体中的,所以在传递参数的时候对用户而言是不可见的,我们平时接触到的网站登录都是这类类型,而复杂点的网站会通过验证码、Cookie等情势来避免爬虫程序摹拟登录,在Web开发中Post要求可以由1个表单发起,可以由爬虫程序如HttpWebRequest、WebClient等发起,下面我们重点来分析它的要求报文:

POST / HTTP/1.1

Accept: text/html, application/xhtml+xml, image/jxr, */*

Accept-Language: zh-Hans-CN,zh-Hans;q=0.5

User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586

Accept-Encoding: gzip, deflate

Host: localhost:4040

Connection: Keep-Alive

Cookie: _ga=GA1.1.1181222800.1463541781

num1=23&num2=12

我们可以注意到此时要求行的要求方法变成了POST,而在报文结尾增加了1行内容,我们称其为“消息体”,这是1个可选的内容,请注意它前面有1个空行。所以,当我们处理1个Posst要求的时候,通过最后1行就能够解析出客户端传递过来的参数,和Get要求相同,我们这里继续使用GetRequestParams来完成解析。

if(this.Method == "POST")

this.Params = GetRequestParams(lines[lines.Length-1]);

实例

现在我们来完成1个简单地实例,服务器自然由我们这里设计的这个服务器来完成咯,而客户端则由Unity来完成由于Unity有简单的WWW可使用。首先来编写服务端,这个继承HttpServer就行了,我们主要来写这里的方法:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using HttpServerLib;

using System.IO;

namespace HttpServer

{

public class ExampleServer : HttpServerLib.HttpServer

{

///

/// 构造函数

///

/// IP地址

/// 端口号

public ExampleServer(string ipAddress, int port)

: base(ipAddress, port)

{

}

public override void OnPost(HttpRequest request)

{

//获得客户端传递的参数

int num1 = int.Parse(request.Params["num1"]);

int num2 = int.Parse(request.Params["num2"]);

//设置返回信息

string content = string.Format("这是通过Post方式返回的数据:num1={0},num2={1}",num1,num2);

//构造响应报文

HttpResponse response = new HttpResponse(content, Encoding.UTF8);

response.StatusCode = "200";

response.Content_Type = "text/html; charset=UTF⑻";

response.Server = "ExampleServer";

//发送响应

ProcessResponse(request.Handler, response);

}

public override void OnGet(HttpRequest request)

{

//获得客户端传递的参数

int num1 = int.Parse(request.Params["num1"]);

int num2 = int.Parse(request.Params["num2"]);

//设置返回信息

string content = string.Format("这是通过Get方式返回的数据:num1={0},num2={1}",num1,num2);

//构造响应报文

HttpResponse response = new HttpResponse(content, Encoding.UTF8);

response.StatusCode = "200";

response.Content_Type = "text/html; charset=UTF⑻";

response.Server = "ExampleServer";

//发送响应

ProcessResponse(request.Handler, response);

}

}

}

由于这里需要对Get和Post进行响应,所以我们这里对OnGet和OnPost两个方法进行了重写,这里的处理方式非常简单,依照1定格式返回数据便可。下面我们来讲说Unity作为客户端这边要做的工作,这里给出关键代码:

//采取GET方式要求数据

IEnumerator Get()

{

WWW www = new WWW ("http://127.0.0.1:4040/?num1=12&num2=23");

yield return www;

Debug.Log(www.text);

}

//采取POST方式要求数据

IEnumerator Post()

{

WWWForm form = new WWWForm ();

form.AddField ("num1", 12);

form.AddField ("num2", 23);

WWW www = new WWW ("http://127.0.0.1:4040/", form);

yield return www;

Debug.Log (www.text);

}

而运行这个实例,我们可以得到下面的结果:

都是谁告知你做服务器开发1定要用Java的啊,现在我们可以写出自己的服务器了,本篇结束,下期见!

unity html get post,使用C#开发HTTP服务器系列之实现Get和Post相关推荐

  1. 使用C#开发HTTP服务器系列之更简单的实现方式

      各位朋友大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是http://qinyuanpei.com.到目前为止,我已经发布了3篇HTTP服务器开发的系列文章.对我个人而言,我非常享受这个从 ...

  2. 《Unity着色器和屏幕特效开发秘笈》—— 3.4 创建BlinnPhong高光类型

    本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第3章,第3.4节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...

  3. 《Unity着色器和屏幕特效开发秘笈》—— 2.1 引言

    本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第2章,第2.1节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...

  4. 《Unity着色器和屏幕特效开发秘笈(原书第2版)》一2.9 打包和混合纹理

    本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈(原书第2版)>一书中的第2章,第2.9节,作者 [英]艾伦朱科尼(Alan Zucconi) [美]肯尼斯拉默斯(Kenneth ...

  5. 《Unity着色器和屏幕特效开发秘笈》—— 1.7 创建渐变纹理来控制漫反射着色...

    本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第1章,第1.7节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...

  6. 基于Unity的2D小游戏 SpeedDown 开发笔记(学习bilibili@[M_Studio]的教学视频

    基于Unity的2D小游戏 SpeedDown 开发笔记(学习bilibili@M_Studio的教学视频) 主要内容:在Sunnyland游戏的设计基础上,新增了物理组件Joint系列.DrawGi ...

  7. 《Unity着色器和屏幕特效开发秘笈》—— 第3章 利用镜面反射让游戏闪耀起来...

    本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第3章,第3.1节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...

  8. 《Unity 2D与3D手机游戏开发实战》简介

    #好书推荐##好书奇遇季#<Unity 2D与3D手机游戏开发实战>,京东当当天猫都有发售.彩色印制,定价89元,网店打折销售更便宜.本书配套源码.PPT课件,适合Unity游戏开发初学者 ...

  9. Unity和Cocos2D在2D游戏开发上的对比

    游戏开发的最好技术是什么:Unity还是Cocos? 在网上你可以找到很多这两种技术的对比.在我们开发游戏之前,我们要了解相关数据和信息并决定使用那种技术.但是人们对这两种技术的对比大多都比较主观.擅 ...

  10. Unity Pro 2018 for Mac(游戏开发工具)

    Unity Pro 2018 for Mac功能特色 一.与您制作流程匹配的可扩展的一体化编辑器 Unity Editor具有多种工具,可在您的开发周期中进行快速编辑和迭代,其中的Play模式可让您实 ...

最新文章

  1. 携手广通,聚焦ITIL——BROADA举办首届BTE认证培训
  2. ArtRage中文版
  3. 自动微分(Automatic Differentiation)
  4. Rancher--Docker容器管理工具的安装与启动
  5. 数据同步结合Crontab
  6. struts2、hibernate工作原理和流程
  7. 项目微管理17 - 双赢
  8. @PropertySource读取properties属性 中文乱码问题
  9. SSL的作用与目前主流的使用场景介绍
  10. php 微信公众 验证失败,微信公众平台token验证失败
  11. 你以为我确定能解决难题?也是硬着头皮向前冲
  12. Android中的数据编码,Android与服务端数据传输的编码处理
  13. Python编程 介绍(入门)
  14. 个人微信公众号做外卖优惠券怎么弄?
  15. kali安装网卡驱动
  16. python threading_Python threading
  17. 运用“孤独九剑”解决项目实际问题(三)
  18. 在 stm32CubeMX下生成程序完成流水灯以及完成STM32的USART串口通讯程序实现STM32系统给上位机(win10)连续发送“hello windows”
  19. 定期清理gitlab的备份监控gitlab备份
  20. Opencv实现停车位识别

热门文章

  1. win10 修改进入 cmd 命令行的默认路径
  2. 2.6 使用for循环遍历文件 2.7 使用while循环遍历文件 2.8 统计系统剩余的内存 2.9 数据类型转换计算(计算mac地址) 3.0 数据类型转换(列表与字典相互转换)...
  3. 医疗物联网解决方案提供商“识凌科技”完成C轮融资
  4. WebLogic(12C)——windows下安装教程
  5. Netty笔记(七)ChannelHandlers and Codes 整合
  6. 《如何阅读一本书》总结
  7. 白话SOA:面向服务+组件+架构
  8. Linux DRM 理解
  9. goland gorm分组查询统计_MySQL·查询(一)
  10. Wireshark实战分析之ARP协议(二)