第九章 网络编程和 分布式开发
DESCRIPTION
第九章 网络编程和 分布式开发. 本章学习要点. 使用 SMTP 服务 通过阅读程序实例了解邮件发送程序的设计 熟悉网络编程的有关知识 通过实例了解使用 Socket 获取数据的方法 了解 Client/Server 通讯程序的编写方法 掌握使用消息队列发送消息及从消息队列中获取消息 了解 Web Service. 9.1 使用 SMTP 服务. 使用 SMTP 服务 , 必须确保你的电脑安装了 IIS 里的 SMTP 服务。 - PowerPoint PPT PresentationTRANSCRIPT
第九章 网络编程和分布式开发
本章学习要点 使用 SMTP 服务 通过阅读程序实例了解邮件发送程序的设计 熟悉网络编程的有关知识 通过实例了解使用 Socket 获取数据的方法 了解 Client/Server 通讯程序的编写方法 掌握使用消息队列发送消息及从消息队列中获取
消息 了解 Web Service
9.1 使用 SMTP 服务 使用 SMTP 服务 , 必须确保你的电脑安装了 IIS 里的
SMTP 服务。 在“默认 SMTP 虚拟服务器”上单击鼠标右键,在弹
出菜单中选择 [ 属性 ] ,弹出“属性 ”对话框。选择[ 访问 ] 选项卡,单击 [ 中继… ] 按钮;在弹出的“中继限制”对话框中,选中“仅以下列表除外”,并确保所用的计算机没有出现在下面的“计算机”列表中。
单击 [ 确定 ] 保存设置。这时,计算机就可以利用系统的 SMTP 服务来传送电子邮件了。
9.2 设计邮件发送程序
窗体布局
txtSubject
txtTo
txtFrom
btnSend
txtContent
9.2 设计邮件发送程序
运行效果
9.2 设计邮件发送程序SMTPemail 代码如下:Imports System.TextImports System.Net.MailPublic Class Form1Inherits System.Windows.Forms.FormPrivate Sub btnSend_Click(ByVal sender As Object, ByV
al e As System.EventArgs)Handles btnSend.Click If CheckFieldsBlank()=False Then Exit Sub SendMail()End Sub
9.2 设计邮件发送程序Private Sub SendMail() Dim strTo As String=txtTO.Text Dim StrFrom As String=txtFrom.Text Dim strSubject As String=txtSubject.Text Dim strContent As String=txtContent.Text Dim SmtpClient As New SmtpClient(“localhost”,25) SmtpClient.Send(strForm, strTo, strSubject, strContent)MessageBox.Show(“ 邮件发送成功!!” , “ 消息” ,Messa
geBoxButtons.OK, MessageBoxIcon.Information)End Sub
9.2 设计邮件发送程序Private Function CheckFieldsBland() As Boolean Dim strMessage As String=“ ” If Not txtFrom.Text.Length>0 Then strMessage=“ 寄件
人” If Not txtTO.Text.Length>0 Then strMessage=strMessag
e+“ 收件人” If Not txtSubject.Text.Length>0 Then strMessage=strMe
sssage+“ 主题” If Not txtContent.Text.Length>0 Then strMessage=strMe
ssage+“ 内容” If strMessage.Length>0 Then MessageBox.Show(“ 字段:” +strMessage+“ 必须有
值!!” , “ 消息” ,MessageBoxButtons.OK, _MessageBoxIcon.Warning)
9.2 设计邮件发送程序
CheckFieldsBlank=False
Else
CheckFieldsBlank=True
End If
End Function
End Class
9.3 网络编程.NET 提供一整组功能相当丰富的类 , 专门
支持 .NET 语言开发网络服务功能的应用程序。这些类大部分集中在 System.Net 和 System.Net.Sockets 两个命名空间中,其中的 System.Net.Sockets 提供 Socket 网络程序所需的 Window Socket 接口, System.Net 则是提供一个通用、简单的网络模型架构,网络程序开发人员在此通用的架构之下,可以快速且方便地进行各种专属协议的网络程序开发。
9.3.1 网络类 System.Net 命名空间包含相当多的类,这些
类以各种通信开发网络程序所需的基础功能,开发人员出除了利用相关类进行网络程序的开发,同时可以运用其方便扩充的特性提供以专属协议为基础而开发的网络服务。
位于 System.Net 空间的类大致可以将其分为几种,其中比较重要的是 WebRequest 和 WebResponse 。
9.3.2 Socket 网络程序 Socket 是一种被广泛接受的跨越网络传输数
据的网络技术 。 System.Net.Sockets 命名空间提供支持 Soc
ket 相关技术的类,其中最主要的便是 Socket 类,封装开发 Socket 和 TcpServer, 这两个类提供网络客户和网络服务器端的连接与数据传输服务。另外一个重要的网络协议 UDP亦有其专属的类, UdpClient, 供 UDP 服务联机和倾听联机。
9.3.2 Socket 网络程序 另外一个位于 System.Net.Sockets 空间的类 Net
workStream 封装跨越网络传输数据所需的功能,派生于 Stream 数据流类,专门用以提供网络功能的类,由于同样继承 Stream 类,因此以文件数据流的数据存取模式进行网络数据的传输操作。
网络联机和数据存取可能发生的异常由 SocketException 类所定义,这个类包含了 Socket 应用程序所可能发生的错误,编写和开发 Socket 应用程序必须适时地捕捉这个异常。
9.4 使用 socket 获取数据 9.4.1 Socket 应用程序要点 使用 Socket 设计网络联机服务的应用程
序,通常必须设计接受客户端应用程序的服务器端应用程序。整个应用程序的运作过程,大致上可以归纳为以下几点:( 1)连接到指定端点:服务器连接到一个指
定的端点,监听客户端;客户端对此服务器的 Socket 端点进行联机操作。
9.4 使用 socket 获取数据( 2)完成服务器联机:建立与主机服务器的
联机。( 3)传送数据至 Socket :客户端应用程序
将指定的数据传送至 Socket 端点。( 4)从 Socket 读取数据:上述步骤的反向操作,在 Socket 端读取所需的数据。( 5)关闭 Socket :停止客户端与服务器的 S
ocket 联机操作。
9.4.2 新建一应用程序
程序窗体
txtPageSource
txtUrl
btnOpen
运行效果
9.4.2 新建一应用程序代码如下: Imports System.Text Imports System.Net Imports System.Net.Sockets Public Class Form1 Private Sub Button1_Click(ByVa1 sender As Syste
m.Object, ByVa1 e As System.EventArgs) Handles btnOpen.Click
’获取的页面 HTML源代码 Dim sPageSource As String=“ ” ’缓冲从服务器获取的字节流 Dim abyteReceive(1024) As Byte
9.4.2 新建一应用程序 ’构造 HTTP GET请求 Dim sGet As String=“GET/HTTP/1.0” & vbCrLf & “Host
: ” & txtUrl.Text & vbCrLf & “Connection:Close” & vbCrLf &vbCrLf
Dim asciiGet As Encoding=Encoding.ASCII ’将 GET请求转换为 ASCII 编码 Dim abyteGet() As Byte=asciiGet.GetBytes(sGet) Try ’从 DNS 获取服务器 IP 地址 Dim hostentry As IPHostEntry=Dns.GetHostEntry(tx
tUrl.Text) Dim hostadd As IPAddress=hostentry.AddressList
(0) ’构造服务器的网络对象 (IP 地址和端口号 )
9.4.2 新建一应用程序 Dim EPhost As IPEndPoint=New IPEndPoint(hostadd, 80) ’建立一个新套接字 Dim sockHTTP As Sockets.Socket=New Sockets.Soc
ket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
’尝试连接到服务器 sockHTTP.connect(EPhost) If sockHTTP.connected=False Then txtPageSource.Text=“无法连接到服务器” Exit Sub End If
9.4.2 新建一应用程序 ’发送 HTTP GET请求 sockHTTP.send(abyteGet, abyteGet.Length, 0) ’从 Socket 中读取数据,并将字节流转换为字符串 Dim iBytes As Integer=1 Do While iBytes>0 iBytes=sockHTTP.receive(abyteReceive, abyteR
eceive.Length, 0) sPageSource &=asciiGet.GetString(abyteReceiv
e, 0, iBytes) Loop sockHTTP.close() sockHTTP=Nothing
9.4.2 新建一应用程序
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
txtPageSource.Text=sPageSource
End Sub
End Class
9.5 编写一个 Client/Server通信程序
Server 窗体
txtPort
btnClose
lblMessage
txtContent
btnListener
9.5 编写一个 Client/Server通信程序
Client 窗体
txtPort
btnWrite
lblMessage
txtContent
btnListener
txtAddress
9.5 编写一个 Client/Server通信程序Server端代码 :Imports System.IOImports System.ThreadingImports System.NetImports System.Net.SocketsPublic Class Form1 Inherits System.Windows.Forms.Form Dim serverThread As Thread Dim tcpListener As TcpListener Dim netStream As NetworkStream
9.5 编写一个 Client/Server通信程序 Dim rdStream As StreamReader Dim wtStream As StreamWriter Dim clientSocket As Socket Private Sub btnListener_Click(ByVal sender As Object, B
yVal e As _ System.EventArgs) Handles btnListener.Click Control.CheckForIllegalCrossThreadCalls = False Try serverThread = New Thread(AddressOf StartListen) serverThread.Start() Form2.Show()
9.5 编写一个 Client/Server通信程序 Catch ex As Exception MessageBox.Show(ex.Message) End Try End SubPrivate Sub btnClose_Click(ByVal sender As Object, ByVal
_e As System.EventArgs) Handles btnClose.Click If (Not netStream Is Nothing) Then rdStream.Close() wtStream.Close() netStream.Close()
9.5 编写一个 Client/Server通信程序 clientSocket.Shutdown(SocketShutdown.Both) clientSocket.Close() lblMessage.Text += " 服务器强行中止连接 " End If If (Not serverThread Is Nothing) Then serverThread.Abort() tcpListener.Stop() End If End Sub Private Sub StartListen()
9.5 编写一个 Client/Server通信程序 Dim clientMsg As String Dim intPort = Integer.Parse(txtPort.Text) tcpListener = New TcpListener(New IPEndPoint _(IPAddress.Parse("127.0.0.1"), intPort)) lblMessage.Text = "等待客户端连接 ....." + vbCrLf Try tcpListener.Start() clientSocket = tcpListener.AcceptSocket() If clientSocket.Connected Then lblMessage.Text += " 一个新用户连接成功 " + vbC
rLf
9.5 编写一个 Client/Server通信程序 netStream = New NetworkStream(clientSocket) rdStream = New StreamReader(netStream) wtStream = New StreamWriter(netStream) End If While (True) clientMsg = rdStream.ReadLine() If clientMsg = "Exit" Then lblMessage.Text += " 客户端终止了连接 " + vb
CrLf Exit Sub End If
9.5 编写一个 Client/Server通信程序 txtContent.Text = clientMsg lblMessage.Text += " 接受了 " + clientMsg.Length.
ToString + _ " 个字符 " + vbCrLf End While Catch ex As SocketException MessageBox.Show("无法打开端口 ") Catch ex As IOException ' 流被关闭 Catch ex As ThreadAbortException '线程正常中止
9.5 编写一个 Client/Server通信程序
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
End Class
9.5 编写一个 Client/Server通信程序Client端代码 :Imports System.IOImports System.NetImports System.Net.SocketsPublic Class Form2 Inherits System.Windows.Forms.Form Dim tcpClient As TcpClient Dim netStream As NetworkStream Dim rdStream As StreamReader Dim wtStream As StreamWriter
9.5 编写一个 Client/Server通信程序Private Sub btnListener_Click(ByVal sender As Object, _ByVal e As System.EventArgs) Handles btnListener.Click Dim intPort = Integer.Parse(txtPort.Text) Try tcpClient = New TcpClient(txtAddress.Text, intPort) lblMessage.Text += " 联机至远程 ...." + vbCrLf btnClose.Enabled = True btnWrite.Enabled = True netStream = tcpClient.GetStream() rdStream = New StreamReader(netStream)
9.5 编写一个 Client/Server通信程序 wtStream = New StreamWriter(netStream) Catch ex As Exception MessageBox.Show("无法连接服务器 ") End Try End SubPrivate Sub btnClose_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnClose.Click wtStream.WriteLine("Exit") wtStream.Flush() lblMessage.Text += "强行断开远程连接 "
9.5 编写一个 Client/Server通信程序 btnWrite.Enabled = False Me.Close() End SubPrivate Sub btnWrite_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnWrite.Click Try wtStream.WriteLine(txtContent.Text) wtStream.Flush() lblMessage.Text += " 发送了 " + txtContent.Text.Len
gth.ToString + _" 个字符 " + vbCrLf
9.5 编写一个 Client/Server通信程序
Catch ex As Exception
MessageBox.Show("无法发送消息 ")
End Try
End Sub
End Class
9.6 使用消息队列发送、获取消息要使用消息队列进行编程,必须保证自己的
计算机安装了消息队列。如果不能确定,请打开“控制面板”→“管
理工具 ” →“计算机管理”,展开左边目录树中的“服务和应用程序”,如果看到了图中的“消息队列”项,说明计算机上已经安装了消息队列服务。如果没有,那就应该从系统安装光盘中安装,步骤像安装 IIS 组件一样把消息队列项打勾进行安装即可。
9.6.1 新建一个消息队列 可以在计算机管理窗口,“专用队列”项上
实现。 也可以在 Visual Studio 2005 中的服务器资源管理器中完成。
将这个队列拖动到窗体上放下,就会在窗体下方的不可见控件区看到消息队列组件 MessageQueue1
9.6.2 编写程序发送消息
发送消息
把消息队列加入窗体
9.6.2 编写程序发送消息
队列中的消息
9.6.3 从消息队列中获取消息
lstMessages
btnView
窗体布局
9.7 Web Service 简介Web Service 可以看做是一个运行在 We
b 服务器上的组件 , 而它的接口通过 HTTP 协议公开 (也就是平时浏览网页的协议 ), 通过一种特定的语言 (XML),遵循一种特定的“语法”(SOAP 协议 ),让所有的计算机都可以访问到它。换句话说 ,Web Service很像是一些通过 Web来调用的函数。
9.7.1 一个 Web Service 的翻译程序本案例是一个基于 Web Service 的翻译程序 ,它
可以把中文译成英文 ,不过它只认识三个词 : 你好、计算机、再见;也只能翻译出三个词来: Hello 、 Thanks 、 Bye 。
在 Visual Web Developer 2005中新建网站,在模板中选择“ ASP.NET Web服务”,在位置一栏填入一个路径( http://localhost/WebSvs ) ,单击确定按钮以后, Visual Web Develper就会自动地在这个地点建立好Web Service需要的所有东西。修改其中的 <WebMethod()> 方法如下:
9.7.1 一个 Web Service 的翻译程序
9.7.2 在浏览器中查看Web Service
Web Service 的说明 Interpret 方法的测试页面
9.7.2 在浏览器中查看Web Service
在文本框中填入“你好” , 单击 [调用 ] ,会看到另一个页面。
对 Web Service 的调用的返回
9.7.3 使用 Web Service
txtChinese
txtEnglish
btnInterpret
窗体设计
添加Web引用
9.7.3 使用 Web Service
添加Web引用的对话框
9.7.3 使用 Web Service
本机上的 Web 服务
9.7.3 使用 Web Service
Web Service “Interpret”
9.7.3 使用 Web Service
双击“翻译”按钮,添加如下代码:
9.7.3 使用 Web Service
运行效果
本章小结 本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、 Client/Server 通信程序的编写与运行。简要的介绍了进程或者设备使用消息队列来通信的方式 , 包括消息队列的创建、编写程序发送消息及从消息队列中获取消息。
.NET Framework 的一个重要功能是 XML Web 服务。 Web 服务中编译并存储在 Web 上的类,可以在Windows 和 Web 应用程序中实例化并使用 Web 服务;也可以把Web 服务看作为多层应用程序创建的组件,只不过是在 Web 上存储并使用这些组件。