本文介绍如何利用VB.Net 通过Windows Sockets (Winsock)以及多线程编程进行桌面电脑与Pocket PC(掌上电脑,简称:PPC)间的双向通信,并且通过当今流行的.net平台编程语言Visaul Basic.Net 2003编写PC端和PPC端程序实现两者的信息交换。

一、概述

如今移动计算设备越来越普及,而PPC与桌面电脑的数据交换更是其必不可少的功能。笔者根据实际的无线PPC开发认为,PPC程序与桌面程序进行通信,除了可以通过SQL Server CE提供的RDA(远程数据存取)和Replication(复制)来完成与桌面SQL Server的数据存取外,另外一种比较方便快捷的方法则是通过Socket与桌面电脑完成信息的交换。

采用Visaul Basic.Net 2003进行PPC和桌面电脑的程序编写,VB.Net已经完全不同于过去的VB,它的诸多新特性以及依托.Net平台强大的面向对象体系使VB.Net焕然一新,不仅编写桌面程序更加轻松快捷而且更可快速的、可视化的开发以Pocket PC为平台的智能设备程序。

.Net框架是一种新的计算平台,可以简单理解为组件库或者类库,类似于MFC和VCL,但是却比它们更加强大和易用。.NET框架具有两个主要组件:公共语言运行库和 .NET 框架类库。公共语言运行库是 .NET 框架的基础,可以将运行库看作一个在执行时管理代码的代理,它提供核心服务(如内存管理、线程管理和远程处理等)。以运行库为目标的代码称为托管代码,而不以运行库为目标的代码称为非托管代码。.NET 框架类库是一个与公共语言运行库紧密集成的可重用的类型集合,该类库是面向对象的,.NET 框架类库能够完成一系列常见编程任务,包括诸如字符串管理、数据收集、数据库连接以及文件访问等任务。

.Net框架精简版是完整.Net框架的子集。它是对完整的 .Net框架进行精简后得到的版本,虽然其规模大大减小,但多数功能仍然保持完整。使用.NET框架精简版可以针对Pocket PC和其他Windows CE .NET设备进行开发和部署,提高开发人员的工作效率

VB.Net编译的桌面程序在目标机器上需要.Net框架的支持才能运行,而编译过的PPC程序需要在目标PPC上装载.Net框架精简版后方可运行。

二、设计思路

在.Net框架中System.Net.Sockets命名空间为需要严密控制网络访问的开发提供了 Windows Sockets (Winsock) 接口的托管实现,该命名空间中包含了与Socket相关的类、接口和枚举,主要包括实现 Berkeley 套接字接口的Socket类、用于 TCP 网络客户端侦听连接的TcpListener类、为 TCP 网络服务提供客户端连接的TcpClient类以及提供无连接的发送和接收用户数据文报 (UDP) 网络服务等。该命名空间下的大部分类都受.Net框架精简版的支持,也就是说实现这些对象的代码完全可以在装载有.Net框架精简版的PPC上运行。

可以把PPC当作局域网中的一个终端来与桌面电脑连接,它们之间有多种物理连接方式,通常可以使用USB线缆配合ActiveSync直接与桌面电脑连接,当然,若PPC和桌面电脑同时具备其它的连接方式,比如无线WiFi(IEEE 802.1x)、蓝牙等都可以组成相应的无线局域网络。

在PPC上编写客户端程序并实现TcpClient类,用于连接、发送和接收流数据。在桌面电脑上我们设计Socket服务端程序并实现TcpListener类和Socket类,用于侦听和接受传入连接的请求。Socket类为网络通信提供了一套非常丰富的方法和属性,服务程序可以使用 Listen 方法侦听连接。Accept 方法处理任何传入的连接请求,并返回可用于与远程主机进行数据通信的 Socket,如果当前使用的是无连接协议(如 UDP),则根本不需要侦听连接。实际上TcpClient类和TcpListener类为 Socket通信提供了比Socket类更简单、对用户更友好的接口,如果编写较简单的应用程序,而且只需同步数据传输,则可以考虑使用 TcpClient、TcpListener 和 UdpClient。

Listener  =  New  TcpListener(System.Net.IPAddress.Parse( " 192.200.0.100 " ), " 10200 " )
Listener.Start()
Label1.Text  =  " 正在 192.200.0.100:10200 处侦听.. "

一、程序的具体实现

1、创建PPC客户端程序

启动Visual Studio .Net 2003,新建Visaul Basic项目,并选择“智能设备应用程序”,选择“Pocket PC”平台的“Windows 应用程序”并创建项目。Pocket PC平台是Windows CE 平台的子集,Windows CE系统的应用更加广泛。项目创建完后,Visaul Studio.Net会创建一个默认的主窗体Form1,在窗体上分别放置两个Panel控件、四个Label控件、三个TextBox控件和两个Button控件。

设计PPC程序的Form窗体与桌面程序没有太多差别,只是少了一些PPC上所不支持的属性,但是属性的名称并没有变化。在PPC上没有窗口最小化的实际意义,主窗体的MinimizeBox属性必须设置成False,否则,当需要退出程序点击标题栏最右侧的关闭按钮时,程序并没有真正退出而是隐藏在后台,程序需要重新激活才能回到前台。或者可以向一个Button添加关闭主窗体的代码:

Private  Sub  Button3_Click( ByVal  sender  As  System.Object,  ByVal  e  As  System.EventArgs)
Handles  Button3.ClickMe .Close()
End Sub

Me 为VB.Net中的关键字,可以引用当前在其中执行代码的类或结构的特定实例。Me 的行为与引用当前实例的对象变量或结构变量类似。此例Me代表主窗体的实例Form1。使 用TcpClient向TcpListener 或 Socket 侦听器连接并交换数据,可以使用下面两种方法之一连接到侦听器:

(1)创建一个 TcpClient,并调用三个可用的 Connect 方法之一。

(2)使用远程主机的主机名和端口号创建 TcpClient。此构造函数将自动尝试一个连接。

TcpClient的Connect 方法使用指定的主机名和端口号将客户端连接到 TCP 主机,重载函数原型为:

使用指定的远程网络终结点将客户端连接到远程 TCP 主机。

Overloads Public Sub Connect(IPEndPoint)

使用指定的 IP 地址和端口号将客户端连接到 TCP 主机。

Overloads Public Sub Connect(IPAddress, Integer)

将客户端连接到指定主机上的指定端口。

Overloads Public Sub Connect(String, Integer)

我们使用指定的主机名称和端口号将客户端连接到 TCP 主机,在堆栈中创建TcpClient对象的实例,当执行退出当前过程或函数时,堆栈中的资源会自动清除,保证内存空间被正确释放。连接成功后要发送和接收数据,使用 GetStream 方法来获取一个 NetworkStream,NetworkStream为基础数据流,调用 NetworkStream 的 Write 和 Read 方法与远程主机之间发送和接收数据。当发送操作结束后使用 TcpClient的Close 方法断开连接、关闭对象并释放与 TcpClient 关联的所有资源。

双击“连接”按钮,编写连接代码:

 ‘创建TcpClient对象的实例Client  =  New  TcpClient‘通过计算机名称和端口号连接到指定的计算机Client.Connect(“ 192.200 . 0.100 ”, 10200 )
SendData  = ”由PPC传递过来的数据 – Author:Risen”‘按一定的编码规则对要传递的数据进行编码Buffer  =  Encoding.UTF8.GetBytes(SendData)‘向已连接的服务程序发送数据Client.GetStream().Write(Buffer,  0 , Buffer.Length)
‘DataAvailable 指示NetworkStream 上是否有可用的数据。如果可以在流上读取数据,则为  true ;
‘否则为  false ,只要有数据存在就等待传输完毕
While  Not  Client.GetStream.DataAvailable()Application.DoEvents()End  While‘接收由服务程序传递回客户端的数据并显示在对话框上If  Client.GetStream.DataAvailable()  ThenClient.GetStream().Read(InBuff,  0 , InBuff.Length)rtndata  =  " 服务程序已经成功收到指令,在 "  &  System.Text.Encoding.Default.GetString(InBuff,  0 , InBuff.Length)MsgBox (rtndata)End  If‘断开连接、关闭对象并释放与 TcpClient 关联的所有资源
Client.Close()

正确编译上述代码还需要在源文件的头部加入使用命名空间的引用,才能正确使用命名空间中的所有枚举、结构、类或模块等。

Imports  System.Net.Sockets ‘ <- 添加需要导入的命名空间
Imports  System.Text  ‘ <- 添加需要导入的命名空间Public  Class  Form

跟踪调试PPC程序需要在适当的模拟器下进行,譬如系统默认的PocketPC2002 模拟器,程序调试无误后可以连接到实际的PocketPC设备运行。实际部署到PPC设备需要在连接的桌面电脑上安装Microsoft ActiveSync将程序传输到用户目录中。

2、创建桌面服务端程序

启动Visual Studio .Net 2003,新建Visaul Basic项目,并选择“Windows应用程序”创建项目。项目创建完后,Visaul Studio.Net会创建一个默认的主窗体Form1,在窗体上分别放置三个Label控件、两个TextBox控件、一个列表框控件和一个Button控件。

创建全局的TcpListener对象的实例来侦听特定的端口,代码片段如下:

‘创建在本机IP地址和端口侦听的TcpListener对象的实例

Listener  =  New  TcpListener(“ 192.200 . 0.100 ”,  10200 )
' 开始侦听
Listener.Start()
‘侦听状态标志
Listening  =  True
Label1.Text  =  " 正在 192.200.0.100:10200 处侦听.. "
通过计时器定时检测侦听器有无连接请求以及多线程来处理接收到的数据:' 声明创建线程时,使用 ThreadStart 委托作为其唯一参数的构造函数创建 Thread 类的新实例
Dim  CurThreadStart  As  ThreadStart
Dim  CurThread  As  Thread' 检测侦听器是否有挂起的连接请求,没有则退出计时器事件
If  Not  Listener.Pending()  ThenExit Sub
End  If
' 有连接的请求则将计时器暂停,准备进行处理
tmProcessRequest.Enabled  =  False
' 创建线程委托,传递需要操作的过程的地址
CurThreadStart  =  New  ThreadStart( AddressOf  ProcessRequest)
CurThread  =  New  Thread(CurThreadStart)
' 开始一个线程
CurThread.Start()
' 重新启动计时器
tmProcessRequest.Enabled  =  True

将计时器触发事件的频率Interval(以毫秒为单位)适当调节可以改变服务程序响应连接请求的快慢。

计时器不断循环,一旦发现有连接的请求就会创建一个线程专门来处理这个连接,创建线程时需要传递处理连接的过程或函数的地址以被线程调用。

服务程序通过已连接的Socket获取数据,接收到的数据按相应的编码规则进行解码并将信息添加到列表框中:

CurThread  =  System.Threading.Thread.CurrentThread()
‘接受挂起的连接请求并返回可用来发送和接收数据的Socket
CurSocket  =  Listener.AcceptSocketWhile  Listening
If  CurSocket.Available  >  0  Then‘接收来自绑定的Socket的数据
Bytes  =  CurSocket.Receive(Buffer, Buffer.Length,  0 )
‘将接收到的数据转化成相应编码的字符串
ReceivedData =  Encoding.UTF8.GetString(Buffer)
SyncLock  CurThreadlbReceived.Items.Add(ReceivedData)
End  SyncLock

TCPListener.AcceptSocket接受挂起的连接请求,并且返回用于发送和接收数据的 Socket,此 Socket 继续用于和新连接上的客户端通信。

SyncLock 语句确保多个线程不会同时执行向列表框添加数据的操作。当线程到达 SyncLock 块时,将计算表达式并保持此互斥性,直到在表达式返回的对象上有锁为止。这防止了表达式在多个线程运行期间更改值,从而避免代码产生意外的结果。

向客户端返回服务端处理后的消息,代码片段如下:

’ 格式化返回消息 - 这是服务器端处理后的结果并返回到客户端。
BacktoClientData = System.DateTime.Now ‘向客户端传递服务端程序处理时的时间

Buffer  =  Encoding.UTF8.GetBytes(BacktoClientData.ToCharArray)

’ 通过打开的套接字将结果发送回客户端应用程序,然后关闭该套接字。

CurSocket.Send(Buffer, Buffer.Length,  0 )
CurSocket.Close()

编译桌面服务端程序运行效果如下图所示:

当服务程序处理完一个连接后就向相应的PPC客户端返回一条成功信息,如下图所示:

至此,PPC客户端程序和桌面服务端程序编写完毕,该系统在安装WindowsXP SP2的桌面电脑和Dell X3i 的PPC上测试通过。

一、结论

本程序简单介绍了PC与PPC之间Socket通信方法,在实际应用中还有很多细节要做,并且还有可以拓展的地vb.net教程方。该模型为实现PC与PPC间复杂的信息交互,创建复杂的无线信息系统提供了一定技术基础。

转载于:https://www.cnblogs.com/shylock/archive/2009/05/21/1486031.html

利用VB.Net编程实现PC与掌上电脑PPC间的双向通信相关推荐

  1. 吐血巨献:VB网络编程(webbrowser+Inet+抓包封包+经验)

    声明:本文部分内容来源与网络! 网络的重要性不用我说,所以关于网络的编程对我我们来说也是非常重要,非常实用的! 但是我在网络上却没有看到多少关于VB网络编程方面的知识,一方面是VB用的人比较少,不会用 ...

  2. VB网络编程(webbrowser+Inet+抓包封包+经验

    网络的重要性不用我说,所以关于网络的编程对我我们来说也是非常重要,非常实用的! 但是我在网络上却没有看到多少关于VB网络编程方面的知识,一方面是VB用的人比较少,不会用就说VB不好(个人认为学好VB以 ...

  3. VB网络编程(webbrowser应用及Inet抓包封包)

    网络的重要性不用我说,所以关于网络的编程对我我们来说也是非常重要,非常实用的! 但是我在网络上却没有看到多少关于VB网络编程方面的知识,一方面是VB用的人比较少,不会用就说VB不好(个人认为学好VB以 ...

  4. VB网络编程(webbrowser+Inet+抓包封包+经验)

    VB网络编程(webbrowser+Inet+抓包封包+经验) 网络的重要性不用我说,所以关于网络的编程对我我们来说也是非常重要,非常实用的!       但 是我在网络上却没有看到多少关于VB网络编 ...

  5. [转]vb高效编程(优化)

    本文适合任何水平的vb编程人员. 一.减少加载窗体数目 每一个加载的窗体,无论可视与否,都要占据一定数量的内存(其数量随窗体上控件的类型和数量,以及窗体上位图的大小等的不同而变化).只在需要显示时才加 ...

  6. RDO和VB数据库编程

    RDO的发展 远程数据对象 (Remote Data Object ,简称RDO) 是位于 ODBC API 之上的一个对象模型薄层,它依赖 ODBC API.选定的 ODBC 驱动程序以及后端数据库 ...

  7. vb外部调用autocad_利用VB与AutoCAD链接进行CAD二次开发

    利用VB进行AutoCAD二次开发,首先应该将VB于CAD进行链接:在编写VB代码之前,在VB编程环境中引用CAD对象库,在编写VB程序代码时,创建CAD对象启动运行CAD程序. VB与CAD进行链接 ...

  8. c语言delay_利用C语言编程单片机,制作可以根据环境光照调整亮度的智能灯

    上一节,我们利用C语言编程单片机仿制了达文西的"古怪手电筒",达成了"在有光的时候就会亮,在没有光的情况下绝对不会亮!"的目标. 其实在此基础上,C语言还能做些 ...

  9. refract推导_我们如何利用Refract来利用React式编程的力量

    refract推导 by Joe McGrath 通过乔麦克格拉斯 我们如何利用Refract来利用React式编程的力量 (How we harnessed the power of reactiv ...

最新文章

  1. TeamViewer密码存储
  2. 莫侵残日噪,正在异乡听
  3. Springboot2集成minidao持久层
  4. SAP License:SAP MM配置中的一些常用的 TCODE
  5. JS DOM操作基础
  6. android线程改变布局,Android线程中设置控件的值提示报错的解决方法
  7. ASP.NET Web API 入门 (API接口、寄宿方式、HttpClient调用)
  8. Eclipse 插件之间互相依赖, 导出Jar包安装, 报错“java.lang.NoClassDefFoundError”
  9. Flutter高级第6篇:事件广播 、事件监听
  10. [2018.07.10 T2]不回文
  11. Allegro中的NET到NET之间的间距设置-网络之间的间距
  12. 【AC自动机模板】(转自木子日匀大神)
  13. 12306网站 =≈=泄露用户信息解读之撞库
  14. html诗集代码简单,自制简单的诗歌搜索系统
  15. TCP/IP协议栈之LwIP(六)---网络传输管理之TCP协议
  16. 攻防实战:如何检测或优化内存中的.NET Tradecraft
  17. 【大牛之路】大牛指导,报酬丰厚的开源项目---“谷歌编程之夏”
  18. erp服务器可以用无线吗,erp可以使用云服务器吗
  19. 苹果应用商店广告评论删除
  20. 街道道路模型,高架桥模型,摊位模型,毁坏房屋模型等等

热门文章

  1. RPC(Remote Procedure Call)
  2. 安卓模拟器内存辅助技术讲解
  3. 电脑自动安装垃圾软件怎么卸载干净
  4. 初、中、高级前端工程师水平怎么划分?
  5. python实时采集与处理声音信号_Python之音频信号处理(一)音频基础知识
  6. Tomcat清理缓存
  7. 如何清除DNS缓存,使用cmd命令清理DNS缓存方法
  8. 哪一刻你才发现青春结束了
  9. 计算机签名数据大小时错误,看过来!介绍开机出现数字签名错误的具体解决步骤...
  10. c语言大作业书店图书管理系统,c语言课程设计 书店管理系统.pdf