`

Visual C# HTTP协议开发

    博客分类:
  • C#
 
阅读更多

 

Visual C# HTTP协议开发

  1. HTTP协议简介
    1. HTTP协议简介
    2. HTTP的请求
    3. HTTP的响应
  2. 与HTTP相关类的简介
    1. WebRequest类
    2. WebResponse类
    3. HttpWebRequest类
    4. HttpWebResponse类
    5. Uri类

HTTP协议简介

HTTP协议简介

在TCP/IP体系结构中,HTTP属于应用层协议,位于TCP/IP协议的顶层。浏览Web时,浏览器通过HTTP协议与Web服务器交换信息。这些信息(文档)类型的格式由MIME定义。

HTTP协议具有以下的特点:

  1. HTTP按客户/服务器模式工作
    HTTP支持客户(一般情况是浏览器)与服务器的通讯,相互传输数据。
    HTTP定义的事务处理由以下四步组成:
    • 客户与服务器建立连接;
    • 客户向服务器提出请求;
    • 如果请求被接受,则服务器送回响应,在响应中包括状态码和所需的文件;
    • 客户与服务器断开连接
    一次HTTP操作称为一次事务transaction)。
  2. HTTP是无状态的
    也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。
  3. HTTP使用元信息作为头标
    HTTP对所有事务都加了头标header)。也就是说,在主要数据前加上一块信息,称为元信息metainformation)。它使服务器能够提供正在传送数据的有关信息。例如,传送对象是哪种类型,是用哪种语言书写的等。
    从功能上讲,HTTP支持四类元信息:一般信息头标、请求头标、响应头标和实体头标。
  4. HTTP支持两种请求和响应格式
    HTTP由不同的两部分组成,一是从浏览器发往服务器的请求,二是服务器对客户的响应。
    HTTP支持两种请求和响应,即简单请求与完全请求和简单响应与完全响应。
  5. HTTP是基于文本的简单协议

HTTP的请求

HTTP的常用请求方法:

方 法 说 明
GET 请求读取一个Web页面
HEAD 请求读取一个Web页面的头标
PUT 请求存储一个Web页面
POST 附加到命名资源中
DELETE 删除Web页面
LINK 连接两个已有资源
UNLINK 取消两个资源之间的已有连接

HTTP请求的格式如下所示:

C http编程 - elite_lcf - elite_lcf的博客 <request-line>
C http编程 - elite_lcf - elite_lcf的博客<headers>
C http编程 - elite_lcf - elite_lcf的博客<blank line>
C http编程 - elite_lcf - elite_lcf的博客[<request-body>]

在HTTP请求中,第一行必须是一个请求行(request line),用来说明请求类型、要访问的资源以及使用的HTTP版本。紧接着是一个首部(header)小节,用来说明服务器要使用的附加信息。在首部之后是一个空行,再此之后可以添加任意的其他数据[称之为主体(body)]。
在HTTP中,定义了大量的请求类型,不过Ajax开发人员关心的只有GET请求和POST请求。只要在Web浏览器上输入一个URL,浏览器就将基于该URL向服务器发送一个GET请求,以告诉服务器获取并返回什么资源。对于www.wzu.edu.cn的GET请求如下所示:

C http编程 - elite_lcf - elite_lcf的博客 GET / HTTP/1.1
C http编程 - elite_lcf - elite_lcf的博客Host: www.wzu.edu.cn 
C http编程 - elite_lcf - elite_lcf的博客User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
C http编程 - elite_lcf - elite_lcf的博客Gecko/20050225 Firefox/1.0.1
C http编程 - elite_lcf - elite_lcf的博客Connection: Keep-Alive

请求行的第一部分说明了该请求是GET请求。该行的第二部分是一个斜杠(/),用来说明请求的是该域名的根目录。该行的最后一部分说明使用的是HTTP 1.1版本(另一个可选项是1.0)。那么请求发到哪里去呢?这就是第二行的内容。
第2行是请求的第一个首部,HOST。首部HOST将指出请求的目的地。结合HOST和上一行中的斜杠(/),可以通知服务器请求的是www.wzu.edu.cn/(HTTP 1.1才需要使用首部HOST,而原来的1.0版本则不需要使用)。第三行中包含的是首部User-Agent,服务器端和客户端脚本都能够访问它,它是浏览器类型检测逻辑的重要基础。该信息由你使用的浏览器来定义(在本例中是Firefox 1.0.1),并且在每个请求中将自动发送。最后一行是首部Connection,通常将浏览器操作设置为Keep-Alive(当然也可以设置为其他值,但这已经超出了本书讨论的范围)。注意,在最后一个首部之后有一个空行。即使不存在请求主体,这个空行也是必需的。

如果要获取一个诸如http://www.wzu.edu.cn/books的www.wzu.edu.cn域内的页面,那么该请求可能类似于:

C http编程 - elite_lcf - elite_lcf的博客 GET /books/ HTTP/1.1
C http编程 - elite_lcf - elite_lcf的博客Host: www.wzu.edu.cn
C http编程 - elite_lcf - elite_lcf的博客User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
C http编程 - elite_lcf - elite_lcf的博客Gecko/20050225 Firefox/1.0.1
C http编程 - elite_lcf - elite_lcf的博客Connection: Keep-Alive

注意只有第一行的内容发生了变化,它只包含URL中www.wzu.edu.cn后面的部分。

要发送GET请求的参数,则必须将这些额外的信息附在URL本身的后面。其格式类似于:

URL ? name1=value1&name2=value2&..&nameN=valueN


该信息称之为查询字符串(query string),它将会复制在HTTP请求的请求行中,如下所示:

C http编程 - elite_lcf - elite_lcf的博客GET /books/?name=Professional%20Ajax HTTP/1.1
C http编程 - elite_lcf - elite_lcf的博客Host: www.wzu.edu.cn
C http编程 - elite_lcf - elite_lcf的博客User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
C http编程 - elite_lcf - elite_lcf的博客Gecko/20050225 Firefox/1.0.1
C http编程 - elite_lcf - elite_lcf的博客Connection: Keep-Alive

另一方面,POST请求在请求主体中为服务器提供了一些附加的信息。通常,当填写一个在线表单并提交它时,这些填入的数据将以POST请求的方式发送给服务器。

以下就是一个典型的POST请求:

C http编程 - elite_lcf - elite_lcf的博客POST / HTTP/1.1
C http编程 - elite_lcf - elite_lcf的博客Host: www.wzu.edu.cn
C http编程 - elite_lcf - elite_lcf的博客User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
C http编程 - elite_lcf - elite_lcf的博客Gecko/20050225 Firefox/1.0.1
C http编程 - elite_lcf - elite_lcf的博客Content-Type: application/x-www-form-urlencoded
C http编程 - elite_lcf - elite_lcf的博客Content-Length: 40
C http编程 - elite_lcf - elite_lcf的博客Connection: Keep-Alive
C http编程 - elite_lcf - elite_lcf的博客name=Professional%20Ajax
&publisher=Wiley

从上面可以发现, POST请求和GET请求之间有一些区别。首先,请求行开始处的GET改为了POST,以表示不同的请求类型。你会发现首部Host和User-Agent仍然存在,在后面有两个新行。其中首部Content-Type说明了请求主体的内容是如何编码的。浏览器始终以application/ x-www-form- urlencoded的格式编码来传送数据,这是针对简单URL编码的MIME类型。首部Content-Length说明了请求主体的字节数。在首部Connection后是一个空行,再后面就是请求主体。与大多数浏览器的POST请求一样,这是以简单的“名称—值”对的形式给出的,其中name是Professional Ajax,publisher是Wiley。你可以以同样的格式来组织URL的查询字符串参数。

正如前面所提到的,还有其他的HTTP请求类型,它们遵从的基本格式与GET请求和POST请求相同。下一步我们来看看服务器将对HTTP请求发送什么响应。

HTTP响应

如下所示,HTTP响应的格式与请求的格式十分类似:

C http编程 - elite_lcf - elite_lcf的博客<status-line>
C http编程 - elite_lcf - elite_lcf的博客<headers>
C http编程 - elite_lcf - elite_lcf的博客<blank line>
C http编程 - elite_lcf - elite_lcf的博客[<response-body>]

正如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。以下就是一个HTTP响应的例子:

C http编程 - elite_lcf - elite_lcf的博客HTTP/1.1 200 OK
C http编程 - elite_lcf - elite_lcf的博客Date: Sat, 31 Dec 2005 23:59:59 GMT
C http编程 - elite_lcf - elite_lcf的博客Content-Type: text/html;charset=ISO-8859-1
C http编程 - elite_lcf - elite_lcf的博客Content-Length: 122
C http编程 - elite_lcf - elite_lcf的博客
C http编程 - elite_lcf - elite_lcf的博客<html>
C http编程 - elite_lcf - elite_lcf的博客<head>
C http编程 - elite_lcf - elite_lcf的博客<title>Wrox Homepage</title>
C http编程 - elite_lcf - elite_lcf的博客</head>
C http编程 - elite_lcf - elite_lcf的博客<body>
C http编程 - elite_lcf - elite_lcf的博客<!-- body goes here -->
C http编程 - elite_lcf - elite_lcf的博客</body>
C http编程 - elite_lcf - elite_lcf的博客</html>
C http编程 - elite_lcf - elite_lcf的博客

 

在本例中,状态行给出的HTTP状态代码是200,以及消息OK。状态行始终包含的是状态码和相应的简短消息,以避免混乱。最常用的状态码有:

  • 200 (OK): 找到了该资源,并且一切正常。
  • 304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
  • 401 (UNAUTHORIZED):客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
  • 403 (FORBIDDEN):客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
  • 404 (NOT FOUND):在指定的位置不存在所申请的资源。

在状态行之后是一些首部。通常,服务器会返回一个名为Date的首部,用来说明响应生成的日期和时间(服务器通常还会返回一些关于其自身的信息,尽管并非是必需的)。接下来的两个首部大家应该熟悉,就是与POST请求中一样的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME类型HTML(text/html),其编码类型是ISO-8859-1(这是针对美国英语资源的编码标准)。响应主体所包含的就是所请求资源的HTML源文件(尽管还可能包含纯文本或其他资源类型的二进制数据)。浏览器将把这些数据显示给用户。
注意,这里并没有指明针对该响应的请求类型,不过这对于服务器并不重要。客户端知道每种类型的请求将返回什么类型的数据,并决定如何使用这些数据。

与HTTP相关类的简介

WebRequest类

WebRequest 是 .NET Framework 的用于访问 Internet 数据的请求/响应模型的抽象基类。使用该请求/响应模型的应用程序可以用协议不可知的方式从 Internet 请求数据。在这种方式下,应用程序处理 WebRequest 类的实例,而协议特定的子类则执行请求的具体细节。

请求从应用程序发送到某个特定的 URI,如服务器上的 Web 页。URI 从一个为应用程序注册的 WebRequest 子代列表中确定要创建的适当子类。注册 WebRequest 子代通常是为了处理某个特定的协议(如 HTTP 或 FTP),但是也可以注册它以处理对特定服务器或服务器上的路径的请求。

由于 WebRequest 类是一个抽象类,所以 WebRequest 实例在运行时的实际行为由 WebRequest.Create 方法所返回的子类确定。

注意 使用 Create 方法初始化新的 WebRequest 实例。不要使用 WebRequest 构造函数。

下面的示例说明如何创建 WebRequest 实例并返回响应。

C http编程 - elite_lcf - elite_lcf的博客// Initialize the WebRequest.
C http编程 - elite_lcf - elite_lcf的博客
WebRequest myRequest = WebRequest.Create("http://www.contoso.com");
C http编程 - elite_lcf - elite_lcf的博客
// Return the response. 
C http编程 - elite_lcf - elite_lcf的博客
WebResponse myResponse = myRequest.GetResponse();
C http编程 - elite_lcf - elite_lcf的博客
// Code to use the WebResponse goes here.
C http编程 - elite_lcf - elite_lcf的博客
// Close the response to free resources.
C http编程 - elite_lcf - elite_lcf的博客
myResponse.Close();

WebResponse类

WebResponse 类是抽象(在 Visual Basic 中为 MustInherit)基类,协议特定的响应类从该抽象基类派生。应用程序可以使用WebResponse 类的实例以协议不可知的方式参与请求和响应事务,而从 WebResponse 派生的协议特定的类携带请求的详细信息。

客户端应用程序不直接创建 WebResponse 对象,而是通过调用 WebRequest 实例上的 GetResponse 方法来创建它。

下面的示例从 WebRequest 创建 WebResponse 实例。

C http编程 - elite_lcf - elite_lcf的博客// Initialize the WebRequest.
C http编程 - elite_lcf - elite_lcf的博客
WebRequest myRequest = WebRequest.Create("http://www.contoso.com");
C http编程 - elite_lcf - elite_lcf的博客
// Return the response. 
C http编程 - elite_lcf - elite_lcf的博客
WebResponse myResponse = myRequest.GetResponse();
C http编程 - elite_lcf - elite_lcf的博客
// Code to use the WebResponse goes here.
C http编程 - elite_lcf - elite_lcf的博客
// Close the response to free resources.
C http编程 - elite_lcf - elite_lcf的博客
myResponse.Close();

HttpWebRequest类

HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。

不要使用 HttpWebRequest 构造函数。使用 WebRequest.Create 方法初始化 HttpWebRequest 的一个新实例。如果 URI 的方案是 http:// 或 https://,则 Create 将返回 HttpWebRequest 实例。

GetResponse 方法向 RequestUri 属性中指定的 Internet 资源发出同步请求并返回包含该响应的 HttpWebResponse 实例。可以使用 BeginGetResponse 和 EndGetResponse 方法对 Internet 资源发出异步请求。

当要向 Internet 资源发送数据时,GetRequestStream 方法返回用于发送数据的Stream实例。BeginGetRequestStream 和EndGetRequestStream 方法提供对发送数据流的异步访问。

下面的示例为 URI http://www.contoso.com/ 创建 HttpWebRequest

C http编程 - elite_lcf - elite_lcf的博客HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/");

HttpWebResponse类

此类包含对 WebResponse 类中的属性和方法的 HTTP 特定用法的支持。HttpWebResponse 类用于生成发送 HTTP 请求和接收 HTTP 响应的 HTTP 独立客户端应用程序。

注意:不要混淆 HttpWebResponse 和 HttpResponse;后者用于 ASP.NET 应用程序,而且它的方法和属性是通过 ASP.NET 的内部 HttpResponse 对象公开的。

决不要直接创建 HttpWebResponse 类的实例。而应当使用通过调用 HttpWebRequest.GetResponse 所返回的实例。

从 Internet 资源返回的公共标头信息公开为该类的属性。有关完整的列表,请参见下表。可以从 Headers 属性以名称/值对的形式读取其他标头。

下表显示可以通过 HttpWebResponse 类的属性使用的公共 HTTP 标头。

标头 属性
Content-Encoding
ContentEncoding
Content-Length
ContentLength
Content-Type
ContentType
Last-Modified
LastModified
服务器
Server

通过调用 GetResponseStream 方法,以 Stream 的形式返回来自 Internet 资源的响应的内容。

下面的示例返回 HttpWebRequest 的 HttpWebResponse

C http编程 - elite_lcf - elite_lcf的博客HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
C http编程 - elite_lcf - elite_lcf的博客HttpWebResponse HttpWResp
= (HttpWebResponse)HttpWReq.GetResponse();
C http编程 - elite_lcf - elite_lcf的博客
// Insert code that uses the response object.
C http编程 - elite_lcf - elite_lcf的博客
HttpWResp.Close()

Uri类

URI 是 Internet 上可由应用程序使用的资源的简洁表示形式。Uri 类定义了属性和方法来处理 URI,包括分析、比较和组合。Uri 类属性是只读的,修改 Uri 实例需使用 UriBuilder 类。

Uri 类只存储绝对 URI(例如“http://www.contoso.com/index.htm”)。相对 URI(例如“/new/index.htm”)必须相对于基 URI 展开,这样才是绝对的。提供了 MakeRelative 方法在必要时将绝对 URI 转换为相对 URI。

URI 由转义编码存储为规范化 URI,所有 ASCII 值大于 127 的字符都被替换为它们的等效十六进制数。为使 URI 具有规范化格式,Uri 构造函数执行以下步骤。

  • 将 URI 方案转换为小写。
  • 将主机名转换为小写。
  • 移除默认端口号和空端口号。
  • 移除多余的段(如“/”和“/test”段)以简化 URI。

使用 ToString 方法,可以将 Uri 类的内容从转义编码的 URI 引用转换为可读的 URI 引用。

一些 URI 包括段标识符或查询。段标识符是 URI 中跟在数字符号 (#) 后的任何文本,存储在 Fragment 属性中。查询信息是 URI 中跟在问号 (?) 后的任何文本,存储在 Query 属性中。

注意:URI 类支持使用以下格式的 IP 地址:四组表示法的 IPv4 协议和冒号分隔的十六进制 IPv6 协议。请记住在 IPv6 地址两边括上方括号,如 http://[::1]。

下面的示例创建 Uri 类的实例,并用它来创建 WebRequest

C http编程 - elite_lcf - elite_lcf的博客Uri siteUri = new Uri("http://www.contoso.com/");
C http编程 - elite_lcf - elite_lcf的博客WebRequest wr 
= WebRequest.Create(siteUri);
分享到:
评论

相关推荐

    Visual C#网络编程技术与实践

    全书共分13章,主要内容包括网络编程原理、Visual C# 2005的套接字以及多线程的开发、基于各种不同协议的网络编程应用模块,并通过几个典型的实例介绍了Visual C# 2005网络编程的实际应用。 本书注重代码的通用性和...

    Visual C# 2005数据库通用模块开发与系统移植 配书目录及代码,这样看代码就方便了

    Visual C# 2005数据库通用模块开发与系统移植 配书目录及代码,这样看代码就方便了 1of 3 环境: Visual Studio .NET 2005 And Microsoft SQL Server 2005 内容简介 Visual C# 2005是Microsoft公司开发的新一代...

    Visual C#.NET串口通信及测控应用典型实例.(电子工业.李江全.邓红涛.刘巧.李伟).part3

    书名:《Visual C#.NET串口通信及测控应用典型实例》(电子工业出版社.李江全.邓红涛.刘巧.李伟) PDF格式扫描版,全书分为8章,共369页。2012年5月出版。 全书压缩打包成3部分,这是第3部分 内容简介 本书从工程...

    Visual C#.NET网络核心编程.pdf

    Visual C#.NET网络核心编程.pdf 网络核心编程 服务器开发 客户端开发 ftp协议开发 POP3协议开发 网络组件开发

    Visual C#网络编程技术与实践源代码

    全书共分13章,主要内容包括网络编程原理、Visual C# 2005的套接字以及多线程的开发、基于各种不同协议的网络编程应用模块,并通过几个典型的实例介绍了Visual C# 2005网络编程的实际应用。 本书注重代码的通用性和...

    Visual.C#2010从入门到精通

    学习以c#的必备书 本书介绍了如何使用Visual C++ 6.0编写Windows应用程序。全书内容全面、结构清晰、由浅入深、注重实用,并结合了大量的实例,以方便读者理解。本书既包含菜单、鼠标、键盘等基本操作,又包含图形...

    C#网络编程技术与实践(源码)

    第3章 开发基于TCP协议的应用程序 第4章 开发基于UDP的应用程序 第5章 开发基于SNMP协议的应用程序 第6章 使用.NET发送邮件  第7章 FTP下载与文件传输  第8章 基于C#.NET的网络管理模块 第9章 编写基于.NET...

    Visual C# 2005程序设计自学手册 随书源码第一部分(共三部)

    起步篇为第1章~第10章,主要介绍认识Visual C#,C#语言基础,C#语句控制,数组、面向对象编程,熟悉WinForms应用程序,WinForms窗体介绍,WinForms应用程序开发常用控件,菜单栏、工具栏和状态栏设计及对话框等内容...

    Hessian协议的C#源代码

    Hessian协议是http://caucho.com/公司开发的一种实用的web服务技术,它采用二进制数据,传输效率比较高,简单易用,是C#.NET/IIS环境快速开发web服务应用的一种解决方案。本资源中包含Hessian协议的C#版源代码,由于...

    C# PPI 相关资料 .zip

    [C#通过PPI协议操作西门子PLC 西门子PLC和计算机通讯用的PPI协议是不公开的。 我花了两个星期的时候,研究PPI协议,破解PPI协议。。 C#通过PPI协议操作西门子PLC 西门子PLC和计算机通讯用的PPI协议是不公开的。 我...

    伺服电机控制工程 伺服电机开发实例 modbus开发源码C# winform位置模式力矩模式 本工程源码编译环境是visual

    本工程源码编译环境是visual studio (最好采用2013以上版本),编写语言是C# ,winform工程。 本工程可以实现电脑上位机与伺服电机进行modbus串口通信(232或485),从而实现电脑对伺服电机的控制,可以一对多进行...

    C#开发UDP协议聊天程序

    讲解如何利用UDP协议开发多点聊天室程序。首先应在不同的计算机中运行聊天室服务程序,然后打开相应的客户发送端窗体,在客户发送端窗体的文本框中输入与之聊天的计算机IP,然后在“发送聊天信息”文本框中输入聊天...

    C#开发典型模块大全

    第1章 认识C#及开发环境 1.1 C#概述 2 1.1.1 C#发展历程 2 1.1.2 C#语言编程环境 2 1.2 .NET Framework 2.0简介 2 1.2.1 什么是.NET Framework 2.0 2 1.2.2 .NET Framework 2.0特性 3 1.3 安装集成...

    C#开发典型模块大全(光盘)第二部分

    明日科技出版的c#开发典型模块大全配套光盘,要的可以下载,因大小受限,分开上传! 第1章 认识C#及开发环境 1.1 C#概述 1.1.1 C#发展历程 1.1.2 C#语言编程环境 1.2.NETFramework2.0简介 1.2.1 什么是....

    C#读取ABPLC驱动程序和ABPLC模拟器源码.zip

    【达摩老生出品,必属精品,亲测校正,质量保证】 资源名:C#读取ABPLC驱动...代码使用最基础的.net2.0开发,完全基于AB的EIP和CIP协议开发。没有使用三方DLL库。程序简单高效。 适合人群:新手及有一定经验的开发人员

    C#视频游戏开发系列课程(1)

    本次课程讲为您讲解一般编程的基础概念,同时也主要讲解Microsoft Visual C# Express版本中的一些特殊编程元素。本次课程将涵盖变量,表达式,声明,操作符,函数,流控制,类,数组,结构和C#类型。 推荐指数...

    C#开发典型模块大全(光盘)

    第1章 认识C#及开发环境 1.1 C#概述 1.1.1 C#发展历程 1.1.2 C#语言编程环境 1.2.NETFramework2.0简介 1.2.1 什么是.NETFramework2.0 1.2.2.NETFramework2.0特性 1.3 安装集成开发环境VisualStudio2005 1.3.1 安装...

    C#编成Modbus TCP连接各种PLC读取写入寄存器源码

    【工控老马出品,必属精品,质量保证,亲测能用】 资源名:C#编成Modbus TCP连接各种PLC读取写入寄存器源码 资源类型:程序源代码 源码说明: C#编成Modbus TCP连接PLC寄存器...适合人群:新手及有一定经验的开发人员

Global site tag (gtag.js) - Google Analytics