第九章 网络编程和 分布式开发 本章学习要点       使用SMTP服务 通过阅读程序实例了解邮件发送程序的设计 熟悉网络编程的有关知识 通过实例了解使用Socket获取数据的方法 了解Client/Server通讯程序的编写方法 掌握使用消息队列发送消息及从消息队列中获取 消息  了解Web Service 9.1 使用SMTP服务  使用SMTP服务,必须确保你的电脑安装了IIS里的 SMTP服务。  在“默认SMTP虚拟服务器”上单击鼠标右键,在 弹出菜单中选择[属性],弹出“属性 ”对话框。选 择[访问]选项卡,单击[中继…]按钮;在弹出的“中 继限制”对话框中,选中“仅以下列表除外”,并 确保所用的计算机没有出现在下面的“计算机”列 表中。  单击[确定]保存设置。这时,计算机就可以利用系 统的SMTP服务来传送电子邮件了。 9.2 设计邮件发送程序 txtFrom btnSend txtTo txtSubject txtContent 窗体布局 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.

Download Report

Transcript 第九章 网络编程和 分布式开发 本章学习要点       使用SMTP服务 通过阅读程序实例了解邮件发送程序的设计 熟悉网络编程的有关知识 通过实例了解使用Socket获取数据的方法 了解Client/Server通讯程序的编写方法 掌握使用消息队列发送消息及从消息队列中获取 消息  了解Web Service 9.1 使用SMTP服务  使用SMTP服务,必须确保你的电脑安装了IIS里的 SMTP服务。  在“默认SMTP虚拟服务器”上单击鼠标右键,在 弹出菜单中选择[属性],弹出“属性 ”对话框。选 择[访问]选项卡,单击[中继…]按钮;在弹出的“中 继限制”对话框中,选中“仅以下列表除外”,并 确保所用的计算机没有出现在下面的“计算机”列 表中。  单击[确定]保存设置。这时,计算机就可以利用系 统的SMTP服务来传送电子邮件了。 9.2 设计邮件发送程序 txtFrom btnSend txtTo txtSubject txtContent 窗体布局 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.

Slide 1

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 2

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 3

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 4

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 5

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 6

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 7

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 8

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 9

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 10

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 11

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 12

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 13

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 14

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 15

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 16

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 17

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 18

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 19

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 20

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 21

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 22

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 23

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 24

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 25

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 26

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 27

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 28

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 29

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 30

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 31

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 32

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 33

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 34

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 35

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 36

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 37

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 38

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 39

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 40

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 41

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 42

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 43

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 44

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 45

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 46

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 47

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 48

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 49

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 50

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 51

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 52

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。


Slide 53

第九章 网络编程和
分布式开发

本章学习要点







使用SMTP服务
通过阅读程序实例了解邮件发送程序的设计
熟悉网络编程的有关知识
通过实例了解使用Socket获取数据的方法
了解Client/Server通讯程序的编写方法
掌握使用消息队列发送消息及从消息队列中获取
消息
 了解Web Service

9.1 使用SMTP服务
 使用SMTP服务,必须确保你的电脑安装了IIS里的
SMTP服务。
 在“默认SMTP虚拟服务器”上单击鼠标右键,在
弹出菜单中选择[属性],弹出“属性 ”对话框。选
择[访问]选项卡,单击[中继…]按钮;在弹出的“中
继限制”对话框中,选中“仅以下列表除外”,并
确保所用的计算机没有出现在下面的“计算机”列
表中。
 单击[确定]保存设置。这时,计算机就可以利用系
统的SMTP服务来传送电子邮件了。

9.2 设计邮件发送程序
txtFrom
btnSend
txtTo
txtSubject

txtContent

窗体布局

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联机操作。

9.4.2 新建一应用程序
btnOpen

txtUrl

txtPageSource

程序窗体

运行效果

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

9.5 编写一个Client/Server通信程序
txtPort
btnListener

lblMessage
btnClose

txtContent

Server窗体

9.5 编写一个Client/Server通信程序
txtAddress
txtPort
btnListener
lblMessage

btnWrite

txtContent

Client窗体

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

编写程序发送消息

队列中的消息

9.6.3 从消息队列中获取消息

lstMessages

btnView

窗体布局

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需要的所有东西。
修改其中的方法如下:

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
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
 双击“翻译”按钮,添加如下代码:

9.7.3 使用Web Service

运行效果

本章小结
本章介绍了网络编程的基本知识,以实例的方式给
出了邮件发送程序、Client/Server通信程序的编写与
运行。简要的介绍了进程或者设备使用消息队列来通
信的方式,包括消息队列的创建、编写程序发送消息及
从消息队列中获取消息。
.NET Framework的一个重要功能是XML Web服务。
Web服务中编译并存储在Web上的类,可以在
Windows和Web应用程序中实例化并使用Web服务;
也可以把Web服务看作为多层应用程序创建的组件,
只不过是在Web上存储并使用这些组件。