530 likes | 728 Views
第九章 网络编程和 分布式开发. 本章学习要点. 使用 SMTP 服务 通过阅读程序实例了解邮件发送程序的设计 熟悉网络编程的有关知识 通过实例了解使用 Socket 获取数据的方法 了解 Client/Server 通讯程序的编写方法 掌握使用消息队列发送消息及从消息队列中获取消息 了解 Web Service. 9.1 使用 SMTP 服务. 使用 SMTP 服务 , 必须确保你的电脑安装了 IIS 里的 SMTP 服务。
E N D
本章学习要点 • 使用SMTP服务 • 通过阅读程序实例了解邮件发送程序的设计 • 熟悉网络编程的有关知识 • 通过实例了解使用Socket获取数据的方法 • 了解Client/Server通讯程序的编写方法 • 掌握使用消息队列发送消息及从消息队列中获取消息 • 了解Web Service
9.1 使用SMTP服务 • 使用SMTP服务,必须确保你的电脑安装了IIS里的SMTP服务。 • 在“默认SMTP虚拟服务器”上单击鼠标右键,在弹出菜单中选择[属性],弹出“属性 ”对话框。选择[访问]选项卡,单击[中继…]按钮;在弹出的“中继限制”对话框中,选中“仅以下列表除外”,并确保所用的计算机没有出现在下面的“计算机”列表中。 • 单击[确定]保存设置。这时,计算机就可以利用系统的SMTP服务来传送电子邮件了。
txtFrom btnSend txtTo txtSubject txtContent 窗体布局 9.2 设计邮件发送程序
运行效果 9.2 设计邮件发送程序
9.2 设计邮件发送程序 • SMTPemail代码如下: Imports System.Text Imports System.Net.Mail Public Class Form1 Inherits System.Windows.Forms.Form Private Sub btnSend_Click(ByVal sender As Object, ByVal 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(“邮件发送成功!!”, “消息”,MessageBoxButtons.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=strMessage+“收件人” If Not txtSubject.Text.Length>0 Then strMessage=strMesssage+“主题” If Not txtContent.Text.Length>0 Then strMessage=strMessage+“内容” 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命名空间提供支持Socket相关技术的类,其中最主要的便是Socket类,封装开发Socket和TcpServer,这两个类提供网络客户和网络服务器端的连接与数据传输服务。另外一个重要的网络协议UDP亦有其专属的类,UdpClient,供UDP服务联机和倾听联机。
9.3.2 Socket网络程序 • 另外一个位于System.Net.Sockets空间的类NetworkStream封装跨越网络传输数据所需的功能,派生于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:停止客户端与服务器的Socket联机操作。
运行效果 btnOpen txtUrl txtPageSource 程序窗体 9.4.2 新建一应用程序
9.4.2 新建一应用程序 代码如下: Imports System.Text Imports System.Net Imports System.Net.Sockets Public Class Form1 Private Sub Button1_Click(ByVa1 sender As System.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(txtUrl.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.Socket(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, abyteReceive.Length, 0) sPageSource &=asciiGet.GetString(abyteReceive, 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
txtPort btnListener lblMessage btnClose Server窗体 txtContent 9.5 编写一个Client/Server通信程序
txtAddress txtPort Client窗体 btnListener lblMessage btnWrite txtContent 9.5 编写一个Client/Server通信程序
9.5 编写一个Client/Server通信程序 Server端代码: Imports System.IO Imports System.Threading Imports System.Net Imports System.Net.Sockets Public 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, ByVal 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 Sub Private 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 += "一个新用户连接成功" + vbCrLf
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 += "客户端终止了连接" + vbCrLf 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.IO Imports System.Net Imports System.Net.Sockets Public 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 Sub Private 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 Sub Private 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.Length.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 编写程序发送消息
lstMessages btnView 窗体布局 9.6.3 从消息队列中获取消息
9.7 Web Service简介 Web Service 可以看做是一个运行在Web服务器上的组件,而它的接口通过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()>方法如下:
Web Service的说明 Interpret方法的测试页面 9.7.2 在浏览器中查看Web Service
对Web Service的调用的返回 9.7.2 在浏览器中查看Web Service • 在文本框中填入“你好”,单击[调用],会看到另一个页面。
txtChinese btnInterpret txtEnglish 窗体设计 添加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