网络编程技术:XML、SOAP、JSON、RSS与Socket的应用与实践
1. XML命名空间与服务应用
1.1 XML命名空间的使用
在处理XML时,我们可以只定义一次命名空间,之后在引用该命名空间中的元素时可重复使用。创建要放置在特定命名空间中的元素时,也可采用相同的重命名方法。需要注意的是,大多数基于XML的语言会将元素置于命名空间中,但不会为属性分配任何命名空间。
1.2 需要XML数据的服务
- 简单Web服务的局限 :简单的Web服务通常允许通过查询字符串参数提供所有输入参数。然而,查询字符串参数受Web浏览器URI规则的限制,长度有限,且难以表示结构化数据。
- 接收XML的Web服务 :需要更详细数据的Web服务通常接受某种形式的XML。例如SOAP,非SOAP的Web服务常使用XML - RPC标准。以Flickr的图像搜索为例,其XML - RPC请求格式如下:
<methodCall>
<methodName>flickr.photos.search</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>tags</name>
<value><string>value</string></value>
</member>
<member>
<name>api_key</name>
<value><string>...</string></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
若要添加更多参数,可添加更多
<member>
元素。使用XML - RPC服务时,需在HTTP POST的正文中发送XML文档,因此需要使用
WebRequest
类而非
WebClient
。
1.3 XML文本的使用
-
定义XML内容
:可以使用
XDocument、XElement等类来构造XML消息,但VB的XML文本功能提供了更简洁的方式。例如:
Dim element As XElement
element = <photo src="http://www.someplace.com/someimage.jpg">
<tag>horse</tag>
<tag>plow</tag>
</photo>
使用XML文本时,可自由地将内容拆分为多行,无需使用行延续符,Visual Studio也会自动缩进XML内容。
-
嵌入变量和代码片段
:XML文本的实用之处在于能够在静态XML内容中嵌入变量和代码片段。例如:
element = <photo src="http://www.someplace.com/someimage.jpg">
<tag><%= pictureKeyword %></tag>
<tag>plow</tag>
</photo>
以下是一个完整的示例,用于构造Flickr图像搜索的XML - RPC请求消息:
Dim writer As New StreamWriter(requestStream)
writer.Write(<methodCall>
<methodName>flickr.photos.search</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>tags</name>
<value>
<string><%= searchKeyword %></string>
</value>
</member>
<member>
<name>api_key</name>
<value><string>...</string></value>
</member>
<member>
<name>perpage</name>
<value><string>10</string></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>)
调用Flickr图像搜索的XML - RPC服务后,会得到XML - RPC响应。若要获取照片信息,需对消息调用
HttpUtility.HtmlDecode()
,然后使用LINQ to XML过滤出
<photo>
元素。
1.4 XML文档的修改
XDocument
和
XElement
类提供了许多方法,可在创建XML文档后轻松修改。不仅可以设置任何元素或属性的值,还可以使用
Add()
、
AddAfterSelf()
、
AddBeforeSelf()
、
RemoveNodes()
、
Remove()
、
ReplaceWith()
等方法插入、删除和操作XML节点树。
2. 返回SOAP数据的服务
Silverlight能与.NET Web服务无缝协作,这些Web服务发送SOAP编码的数据。虽然从技术上讲,可以使用Silverlight的XML处理(如
XDocument
类)来创建请求消息和解析响应消息,但在Visual Studio中添加服务引用会更简单。而且,这种方法适用于任何基于SOAP的Web服务,Silverlight无法区分不同的SOAP服务,也不知道服务背后的代码实现。添加Web引用后,Visual Studio会创建所需的代理类,包含每个Web方法的异步方法和事件。
3. 返回JSON数据的服务
3.1 JSON简介
JavaScript对象表示法(JSON)是一种对象表示语法,有时可作为XML的轻量级替代方案。当使用返回JSON数据且无SOAP替代方案的Web服务时,需要使用JSON序列化器。Silverlight提供了两种解析JSON数据的方法:使用JSON反序列化器或LINQ to JSON。在处理JSON数据之前,需要添加对
System.Runtime.Serialization.dll
、
System.ServiceModel.dll
和
System.ServiceModel.Web.dll
三个程序集的引用。
3.2 JSON数据的反序列化
以Yahoo!的图像搜索服务为例,其返回的JSON数据格式如下:
{"ResultSet":{
"totalResultsAvailable":"957841",
"totalResultsReturned":10,
"firstResultPosition":1,
"Result":[
{
"Title":"tree_frog.jpg",
"Summary":"Red-Eyed Tree Frog",
"Url":"http:\/\/www.thekidscollege.com\/images\/animals\/redeyetree_frog.jpg",
...
},
{
"Title":"tree_frog_large-thumb.jpg",
"Summary":"Before I came back in though I got another shot of the frog.",
"Url":"http:\/\/www.silveriafamily.com\/blog\/john\/treefrog.jpg",
...
}
]
}}
要对JSON数据进行反序列化,需要创建与JSON数据结构匹配的类。以下是所需的类:
Public Class SearchResults
Public ResultSet As SearchResultSet
End Class
Public Class SearchResultSet
Private _totalResultsAvailable As Integer
Public Property totalResultsAvailable() As Integer
...
End Property
Private _totalResultsReturned As Integer
Public Property totalResultsReturned() As Integer
...
End Property
Private _result As SearchResult()
Public Property Result() As SearchResult()
...
End Property
End Class
Public Class SearchResult
Private _title As String
Public Property Title() As String
...
End Property
Private _summary As String
Public Property Summary() As String
...
End Property
Private _url As String
Public Property Url() As String
...
End Property
End Class
反序列化的步骤如下:
1. 创建
DataContractJsonSerializer
实例,指定要序列化或反序列化的类型:
Dim serializer As New DataContractJsonSerializer(GetType(SearchResults))
-
使用
ReadObject()反序列化JSON数据:
Dim results As SearchResults = CType(serializer.ReadObject(jsonData), SearchResults)
3.3 示例代码
以下是一个完整的示例,用于搜索Yahoo!图像并显示结果:
Private Sub cmdGetData_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim client As New WebClient()
Dim address As New Uri( _
"http://search.yahooapis.com/ImageSearchService/V1/imageSearch?" & _
"appid=YahooDemo&query=" & HttpUtility.UrlEncode(txtSearchKeyword.Text) & _
"&output=json")
AddHandler client.OpenReadCompleted, AddressOf client_OpenReadCompleted
client.OpenReadAsync(address)
End Sub
Private Sub client_OpenReadCompleted(ByVal sender As Object, _
ByVal e As OpenReadCompletedEventArgs)
Dim serializer As New DataContractJsonSerializer(GetType(SearchResults))
Dim results As SearchResults = CType(serializer.ReadObject(e.Result), _
SearchResults)
lblResultsTotal.Text = results.ResultSet.totalResultsAvailable & " _
total results."
lblResultsReturned.Text = results.ResultSet.totalResultsReturned & " _
results returned."
gridResults.ItemsSource = results.ResultSet.Result
End Sub
4. RSS的使用
4.1 RSS简介
Really Simple Syndication(RSS)是一种基于XML的格式,用于发布频繁更新内容的摘要,如博客文章或新闻故事。这些文档称为提要,客户端应用程序(RSS阅读器)可以定期检查RSS提要,并通知用户新添加的项目。
4.2 读取RSS提要
.NET 3.5引入了支持RSS 2.0或Atom 1.0格式的类,Silverlight借用了这些类,可无需繁琐的XML解析代码来读取提要信息。这些类定义在
System.ServiceModel.Syndication
命名空间中,使用时需要添加对
System.ServiceModel.Syndication.dll
程序集的引用。
4.3 RSS使用注意事项
- 跨域规则 :使用RSS时,受跨域规则的限制。如果尝试访问不允许跨域访问的Web服务器上的提要,会出现错误。而且,提要中的链接指向的页面也需要在允许跨域访问的Web服务器上。
- HTML内容显示 :RSS提要中的项目通常指向完整的HTML页面,但无法在Silverlight内容区域以正确的格式显示这些HTML内容。更好的方法是在当前HTML页面的其他部分显示,例如在Silverlight控件下方。
4.4 示例代码
以下是一个简单的示例,用于读取ZDNet的博客新闻提要:
Private Sub cmdGetData_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim client As New WebClient()
Dim address As New Uri("http://feeds.feedburner.com/ZDNetBlogs")
AddHandler client.OpenReadCompleted, AddressOf client_OpenReadCompleted
client.OpenReadAsync(address)
End Sub
Private Sub client_OpenReadCompleted(ByVal sender As Object, _
ByVal e As OpenReadCompletedEventArgs)
Try
Dim reader As XmlReader = XmlReader.Create(e.Result)
Dim feed As SyndicationFeed = SyndicationFeed.Load(reader)
gridFeed.ItemsSource = feed.Items
reader.Close()
Catch
lblError.Text = "Error downloading feed."
End Try
End Sub
要显示
SyndicationItem
对象的信息,可使用自定义绑定表达式。以下是一个示例:
<data:DataGrid>
<data:DataGrid.Columns>
<data:DataGridTextColumn Binding="{Binding Title.Text}"
ElementStyle="{StaticResource DataGridWrapStyle}" />
<data:DataGridTextColumn Width="400"
Binding="{Binding Summary.Text, Converter={StaticResource HtmlCleanUp}}"
ElementStyle="{StaticResource DataGridWrapStyle}" />
</data:DataGrid.Columns>
</data:DataGrid>
当在
DataGrid
中点击项目时,以下事件处理程序会获取对应的
SyndicationItem
对象,并将
<iframe>
指向完整的文章页面:
Private Sub gridFeed_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
' Get the selected syndication item.
Dim selectedItem As SyndicationItem = CType(gridFeed.SelectedItem, _
SyndicationItem)
' Find the <iframe> element on the page.
Dim element As HtmlElement = HtmlPage.Document.GetElementById("rssFrame")
' Point the <iframe> to the full page for the selected feed item.
element.SetAttribute("src", selectedItem.Links(0).Uri.ToString())
End Sub
5. 套接字的使用
5.1 HTTP的局限性
虽然HTTP最初是为下载简单的HTML文档而开发的,但它也能很好地作为XML文档以及与Web服务交互的请求和响应消息的传输机制。然而,HTTP存在一些显著的缺点:
-
速度问题
:HTTP是基于传输控制协议(TCP)的高级标准,其速度不如原始网络连接。
-
请求模式限制
:HTTP使用请求模型,客户端必须主动请求数据,服务器无法在有新信息时主动回调客户端。这使得HTTP不适合实时互联网游戏、股票监控等应用。
5.2 理解套接字和TCP
- 套接字的定义 :套接字是网络上的端点,由IP地址和端口号组成。IP地址用于在网络或互联网上标识计算机,端口号对应于通过网络进行通信的特定应用程序或服务。
- Silverlight支持的套接字 :Silverlight支持流套接字,使用TCP通信。TCP是一种面向连接的协议,具有内置的流量控制、错误纠正和排序功能,可确保数据的可靠传输。
- TCP连接的建立 :创建TCP连接需要进行三阶段的握手过程:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([服务器]):::startend -->|1. 被动打开,进入监听模式| B(等待客户端请求):::process
C([客户端]):::startend -->|2. 使用IP地址和端口号主动打开| D(发送请求):::process
D -->|包含客户端序列号| E(服务器发送确认消息):::process
E -->|3. 客户端响应确认| F(连接建立,可双向传输数据):::process
1. 服务器通过被动打开进入监听模式,等待传入请求。
2. 客户端使用IP地址和端口号进行主动打开,服务器以包含客户端序列号的预定格式发送确认消息。
3. 客户端响应确认,连接准备好双向传输数据。
5.3 端口使用注意事项
端口号并非对应物理实体,而是用于区分同一计算机上的不同应用程序端点。例如,运行Web服务器时,计算机通常在端口80上响应请求,其他应用程序可能使用端口8000。Silverlight允许使用4502 - 4534范围内的任何端口打开连接。
综上所述,在网络编程中,我们可以根据不同的需求选择合适的技术,如XML、SOAP、JSON、RSS和套接字,以实现高效、可靠的数据传输和交互。
6. 不同网络数据处理技术对比
6.1 XML、SOAP、JSON和RSS的对比
| 技术类型 | 特点 | 适用场景 | 处理方式 |
|---|---|---|---|
| XML | 结构化标记语言,可自定义标签,适合复杂数据结构 | 数据交换、配置文件等 |
使用
XDocument
、
XElement
等类处理,可结合LINQ to XML
|
| SOAP | 基于XML的协议,用于Web服务通信,有严格的消息格式 | 企业级Web服务交互 | 在Visual Studio中添加服务引用,使用代理类 |
| JSON | 轻量级数据交换格式,易于阅读和编写 | 前后端数据交互、移动应用数据传输 | 使用JSON序列化器或LINQ to JSON解析 |
| RSS | 基于XML的内容聚合格式,用于发布更新信息 | 博客、新闻等内容的订阅 |
使用
System.ServiceModel.Syndication
命名空间下的类读取
|
6.2 网络传输协议对比
| 协议类型 | 特点 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| HTTP | 基于TCP的应用层协议,请求 - 响应模式 | 简单易用,广泛支持 | 速度相对较慢,服务器无法主动推送 | 静态网页、Web服务请求 |
| TCP | 面向连接的传输层协议,提供可靠的数据传输 | 数据可靠,有流量控制和错误纠正 | 建立连接开销大 | 对数据准确性要求高的场景,如文件传输 |
7. 实际应用案例分析
7.1 综合数据获取应用
假设要开发一个综合信息获取应用,需要从不同的Web服务获取数据,包括XML - RPC服务、SOAP服务和JSON服务。以下是实现该应用的步骤:
1.
获取XML - RPC服务数据
- 构造XML请求消息,可使用XML文本功能嵌入变量。
- 使用
WebRequest
类发送HTTP POST请求,将XML消息放在请求体中。
- 接收响应消息,使用
HttpUtility.HtmlDecode()
解码,再用LINQ to XML过滤所需数据。
vb
Dim writer As New StreamWriter(requestStream)
writer.Write(<methodCall>
<methodName>flickr.photos.search</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>tags</name>
<value>
<string><%= searchKeyword %></string>
</value>
</member>
<member>
<name>api_key</name>
<value><string>...</string></value>
</member>
<member>
<name>perpage</name>
<value><string>10</string></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>)
2.
获取SOAP服务数据
- 在Visual Studio中添加SOAP服务引用,生成代理类。
- 使用代理类的异步方法调用Web服务,处理响应事件。
3.
获取JSON服务数据
- 添加对
System.Runtime.Serialization.dll
、
System.ServiceModel.dll
和
System.ServiceModel.Web.dll
的引用。
- 创建与JSON数据结构匹配的类。
- 使用
DataContractJsonSerializer
反序列化JSON数据。
vb
Dim serializer As New DataContractJsonSerializer(GetType(SearchResults))
Dim results As SearchResults = CType(serializer.ReadObject(jsonData), SearchResults)
7.2 RSS新闻聚合应用
开发一个RSS新闻聚合应用,可按以下步骤进行:
1.
添加引用
:添加对
System.ServiceModel.Syndication.dll
的引用。
2.
下载RSS提要
:使用
WebClient
类的
OpenReadAsync
方法下载RSS提要。
Private Sub cmdGetData_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim client As New WebClient()
Dim address As New Uri("http://feeds.feedburner.com/ZDNetBlogs")
AddHandler client.OpenReadCompleted, AddressOf client_OpenReadCompleted
client.OpenReadAsync(address)
End Sub
-
解析提要
:使用
SyndicationFeed.Load方法将XML内容加载到SyndicationFeed对象中。
Private Sub client_OpenReadCompleted(ByVal sender As Object, _
ByVal e As OpenReadCompletedEventArgs)
Try
Dim reader As XmlReader = XmlReader.Create(e.Result)
Dim feed As SyndicationFeed = SyndicationFeed.Load(reader)
gridFeed.ItemsSource = feed.Items
reader.Close()
Catch
lblError.Text = "Error downloading feed."
End Try
End Sub
-
显示信息
:使用自定义绑定表达式显示
SyndicationItem对象的信息。
<data:DataGrid>
<data:DataGrid.Columns>
<data:DataGridTextColumn Binding="{Binding Title.Text}"
ElementStyle="{StaticResource DataGridWrapStyle}" />
<data:DataGridTextColumn Width="400"
Binding="{Binding Summary.Text, Converter={StaticResource HtmlCleanUp}}"
ElementStyle="{StaticResource DataGridWrapStyle}" />
</data:DataGrid.Columns>
</data:DataGrid>
-
处理点击事件
:当用户点击新闻项时,将
<iframe>指向完整的文章页面。
Private Sub gridFeed_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
' Get the selected syndication item.
Dim selectedItem As SyndicationItem = CType(gridFeed.SelectedItem, _
SyndicationItem)
' Find the <iframe> element on the page.
Dim element As HtmlElement = HtmlPage.Document.GetElementById("rssFrame")
' Point the <iframe> to the full page for the selected feed item.
element.SetAttribute("src", selectedItem.Links(0).Uri.ToString())
End Sub
8. 总结与展望
8.1 总结
在网络编程中,XML、SOAP、JSON、RSS和套接字等技术各有其特点和适用场景。XML适用于复杂数据结构的表示和交换;SOAP为Web服务通信提供了标准化的协议;JSON以其轻量级和易于解析的特点在前后端数据交互中广泛应用;RSS方便了内容的订阅和更新;套接字则为需要高性能和实时通信的应用提供了可能。通过合理选择和使用这些技术,我们可以构建出高效、可靠的网络应用。
8.2 展望
随着网络技术的不断发展,这些网络数据处理技术也将不断演进。例如,JSON可能会在更多的领域替代XML,成为主流的数据交换格式;SOAP服务可能会与微服务架构相结合,提供更灵活的服务组合;RSS可能会与社交媒体等新兴平台融合,提供更丰富的内容订阅体验;套接字技术可能会在物联网、实时通信等领域发挥更大的作用。同时,新的网络协议和数据处理技术也可能会不断涌现,为网络编程带来更多的可能性。
总之,网络编程是一个充满挑战和机遇的领域,我们需要不断学习和掌握新的技术,以适应不断变化的网络环境。
超级会员免费看
1179

被折叠的 条评论
为什么被折叠?



