闲来无事,今天休息,放点资料上来活下人气!(转)

liaolwj 2003-09-04 09:58:48
使用PowerBuilder 6.0开发分布式三层应用程序
作者:陈俊明

本文档是在PowerBuilder 6.0的基础上产生。所有内容均为实践中所得,所有代码在程序中均通过(机器配置:P200/64M/6.4G)。在文章的最后,还有一个通用的服务器框架应用程序,您可对服务器程序只加入您的分布对象即可完成服务器程序。
由于水平所限,错误在所难免,还请大家指正,我的EMAIL是CHENJM@163.NET,发邮件时请在主题中加入POWERBUILDER字样。

概述
只要有过MIS程序编程经验的程序员都知道,一般情况下,整个MIS应用系统分为两部份,即分为数据库服务器和前台程序(即平时我们所说的C/S结构)。在这种体系统结构下,应用系统的逻辑实现几乎都是通过前台程序即客户端来体现,少量保存在数据库服务器中(以存储过程的形式),在业务和管理形式没有变化的情况下,这种结构工作得非常好。可是当业务逻辑发生变化时,我们就需要对客户端程序进行修改和重新编译,并把新程序发布给用户,有时(大多数时候)还要对客户重新进行培训。可以说,C/S体系结构不能很好的适应未来系统的发展。正因为此,在软件界逐渐形成另一种应用体系结构即数据库服务器、应用服务器和前台程序。在这种结构下,几乎所有的商业逻辑都在应用服务器中实现,前台程序只是通过应用服务器提供的接口来实现其功能。修改商业逻辑,只需要修改应用服务器程序,只要保持对前台程序的接口不发生变化,前台程序可以不用作任何修改即可实现功能的转变,并体现新的商业逻辑,其优点是显而易见的。
PowerBuilder 6.0是当今用于与数据库有关的应用系统开发的首选工具,它支持几乎所有当前流行的数据库服务器,具有可视化的面向对象编程环境,使其非常易于使用。从5.0版本开始,PowerBuilder支持C/S体系结构和分布式计算体系结构的应用。本文的主要目的是通过对用PowerBuilder开发分布式计算体系结构应用的学习,使读者能够基本掌握分布式计算体系结构应用的开发。
本文面向的读者不是PowerBuilder的未入门者,本文假设读者已经对PowerBuilder有了比较全面和深入的了解,如对PowerScript语言和PowerBuilder中控件的属性及方法都非常熟悉,但是希望对PowerBuilder的功能有更深入的了解,特别是相了解分布式计算体系结构的应用的开发。关于有关知识的更深入的介绍请见PowerBuilder的ONLINE BOOK。
本文是以下列方式组织的:
第一章 什么是分布式计算结构体系。如果您对这非常熟悉,可以略过。
第二章 PowerBuilder分布式应用编写入门。本章通过一些实际的代码对怎样使用PowerBuilder编写分布式应用程序作了详细介绍。
第三章 深入了解PowerBuilder应用中分布式体系的工作原理。这些都是作者在实践中总结出来的经验和教训,有助于您在开发程序的过程中少走弯路。
第四章 应用服务器程序的一个例子。通过这个例程,您可以只修改少量代码或不修改,即可用于您的应用中。
第五章 使用PowerBuilder编写WEB服务器应用程序。作为分布式应用的一个特例,PowerBuilder当然支持WEB服务器应用程序的开发工作,本章有助于您在这方面的入门。

...全文
54 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuxutj 2003-09-04
  • 打赏
  • 举报
回复
还有吗?多总结一些顺便给我发一份儿
xuxutj_42@yahoo.com.cn
先谢了
jdsnhan 2003-09-04
  • 打赏
  • 举报
回复
学习先。
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
PB6.5中OLE控件的三个缺点
2000-03-19 00:00:00· 安美建·powerBuder编程高手

--------------------------------------------------------------------------------
捎赑B6.0在汉字方面有问题,因此利用Sybase公司免费提供的PB6.5补丁程序进行升级是PB6.0用户较现实的选择。但笔者在用升级后的PB6.5开发一个需串口操作微机数据库项目的过程中,发现PB6.5中的OLE(Microsoft喜欢叫她ActiveX)在汉字方面仍存在一些问题。
  首先在PB中创建一个窗口w_1。

  问题一 嵌入PB中的微软OLE控件MSCOMM32.OCX的output属性为char变量或char()函数时,程序执行时为非法。

  把MSCOMM32.OCX嵌入到w_1中,命名为ole_1。执行以下语句时程序将提示"在进入output属性时非法,并中断程序":
ole_1.object.output=char(48)
  从以下两点来看,这个错误不应该存在:(1) 从MSCOMM32.OCX本身来看,output属性(见MSDN中有关MSCOMM32的内容)完全可以等于与PB中char变量和char()函数相对应的变量和函数。(2) MSCOMM32嵌入到PB中后,PB把其output属性变量当作any型变量来处理。Any型变量就包括char(或character)型变量。
  处理这个问题的简单方法是:把char变量或函数的值赋予一个string变量,然后再使output属性值为该string变量值。如:
ole_1.object.output=string(char(48)) 这样PB将正常运行。

  问题二 OLE控件接收到的汉字数据无中生有。

  利用VC++5.0的MFC ActiveX Controlwizard的所有默认选项创建一个ActiveX控件TempControl,并增加一个CString属性SetWord(m_setWord为该属性的CString实例);在OnDraw()函数中用TextOut函数在屏幕上显示m_setWord;在处理给SetWord赋值的函数OnSetWordChanged()中加上InvalidateControl(),以便显示更新。
把TempControl控件嵌入w_1中,命名为ole_2。执行如下代码:
ole_2.object.setword="开始通讯实验"
  结果在屏幕上TempControl控件内不但显示了"开始通讯试验",而且后面还增加了多余的字符。多余字符且具有一定的规律性,即总是在汉字末尾首先出现0号ASCII字符,随后有几个莫名其妙的汉字或ASCII字符。如果用户还停留在用PB6.0的时代,那您的运气将更糟(在PB6.0调试状态执行就见不到需要的汉字,更不用说编译成exe文件后,将汇合其他众所周知的汉字问题了)。但当SetWord为普通可打印ASCII字符时不出现该现象。
  在这个简单的控件里我们没有其他复杂的功能,只是简单地由w_1把汉字数据赋予TempControl控件唯一的属性SetWord,然后由TempControl控件显示在屏幕上。使用如此简单的控件竟有问题,因此PB6.5中给 控件进行汉字赋值是不方便的。
  在这个问题里,Microsoft的产品也不是完美无缺的。一般地,CString实例是不包括0号ASCII字符的。即把一组中间包括NULL(0号ASCII字符)字符的字符串付予CString的实例时,该实例自动取NULL以前的字符,即m_setWord不包括NULL及其后面的字符。当然了,在Microsoft产品内部不存在这个问题。这个问题的解决方法是很简单的,只需在TempControl中OnSetWordChanged()函数的开头把NULL以后的内容去掉就可以了。但现成的商业控件就没这么轻而易举了。

  问题三 在PB中读取到的OLE控件内部汉字数据将可能残缺不全。

  在TempControl控件的OnSetWordChanged()中InvalidateControl()之前加上:
m_setWord="字符已变";
  即在控件内部改变m_setWord值。在问题二所示那行PB程序后增加如下语句:
string word
word=ole_2.object.setword
messagebox("",word)
  运行时,对word值与"字符已变"进行对比来看,"字符"尚存,"已变"二字真的已经被变成其他莫名其妙的字符了。该问题难以补救。
综合以上看来,PB6.5的OLE在汉字数据处理方面有一定的缺点。
奉献如上内容以便众同仁在项目设计时,谨慎处理PB6.5的OLE控件功能。
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
2.用流式Socket 开发网络聊天程序

  网络聊天程序通常包含两个部分:服务程序和客户程序。服务程序一直处于监听状态,当听到客户程序的呼叫时,就创建一个Socket对它进行响应。下面用流式Socket开发一个两节点聊天程序:

  (1)编写服务程序

  服务程序界面如图1所示。在主窗口的Open事件中创建流式Socket的一个实例:

  sSock=Create SockStream//sSock为实例变量

  在“监听”按钮的Clicked事件中加入下列代码:

  ulAddr=ws.inet—addr(″202.140.1.20″)

  //将服务器地址转为ulong类型

  sSock.bind(ulAddr,2000)//将流式Socket绑定到ulAddr地址的2000号端口上

  sSock.listen(5)//监听上述地址和端口,参数为请求队列长度,最大值为5

  uiSockType=sSock.accept(ulClientAddr,iClientPort)

  //接受客户请求,参数填入了客户Socket的地址和端口,返回值为客户Socket类型

  sAccept=Create Socket

  //创建一个Socket响应客户请求

  ulParam=1

  sAccept.initsocket(uiSockType)

  //与客户Socket类型相同

  sAccept.ioctlsocket(ws.FIONBIO,ulParam)

  //异步模式

  Timer(0.5)

  //启动定时器,以0.5秒的间隔接收数据

  在Timer事件中加入下列代码来处理到达的数据:

  buf=Blob(Space(256))//定义缓冲区大小

  sAccept.recv(buf,Len(buf),0)

  //接收到达的数据

  mle—1.Text=mle—1.Text+Trim(String(buf))

  //显示消息

  在“发送”按钮的Clicked事件中加入下列代码:

  buf=Blob(mle—2.Text+″~r~n″)

  //将mle—2中的内容放入发送缓冲区

  sAccept.send(buf,Len(buf),0)

  //将buf中的内容发给对方

  mle—2.Text=″ ″

  //清除已发送的内容

  在“退出”按钮的Clicked事件中加入下列代码:

  sAccept closesocket()//关闭Socket

  Destroy sAccept

  sSock.closesocket()

  Destroy sSock//清除Socket

  (2)编写客户程序

  设计如图2所示的窗口,其Open事件的代码为:

  sClient=Create SocketStream

  //创建流式Socket

  ulParam=1

  //1表示异步模式(即非阻塞模式)

  Timer(0.5)//启动定时器,以0.5秒的间隔检查是否有数据到达

  sClient.ioctlsocket(ws.FIONBIO, ulParam)

  //将sClient设置为异步模式

  在“连接” 按钮的Clicked事件中加入下列代码:

  ulAddr=ws.inet—addr(″202.140.1.20″)

  //服务器地址

  If sClient.wsconnect(ulAddr,2000)=-1 Then//连接到服务器的2000号端口

  MessageBox(′Socket′,″连接服务器失败″)

  End If

  Timer事件和“发送”按钮的Clicked事件的代码与服务程序相同,只需将套接字对象sAccept改为sClient即可。

  声明:缺省情况下创建的流式Socket对象使用同步模式,可根据需要将其转换成异步模式。在同步模式下,一些Winsock函数调用在完成处理之前不会把控制权还给程序,导致程序无响应。例如,在数据到达之前,recv()调用将一直处于等待状态。在上面的服务程序中,用于监听客户连接的Socket使用了同步模式,响应客户请求的Socket使用了异步模式,客户程序中的Socket也使用了异步模式。

  运行服务程序,点击“监听”进入等待状态;运行客户程序,点击“连接”进行呼叫。建立连接后,就可以聊天了。在mle—2中输入消息,点击“发送”就可传给对方,对方发过来的消息显示在mle—1中。
liying1212 2003-09-04
  • 打赏
  • 举报
回复
up
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
用PB编写WinSock TCP/IP应用程序
PB中的套接字是通过Winsock.pbl库来提供的,它封装了套接字编程中用到的数据结构和过程,在功能上类似于VB中的Winsock控件。

  Winsock.pbl中定义了两种类型的Socket:流式Socket和数据报式Socket。流式Socket需要连接到另一个处于监听状态的流式Socket后才能进行通信,是基于连接的,其可靠性高;数据报式Socket无需建立连接,源主机发出的报文在网络中经过存储转发后到达目的主机,效率高但可靠性低。编程时,根据应用环境和需求选择其中一种,若通信子网相当可靠,可考虑采用数据报式Socket。



图1

  用PB编写WinSock TCP/IP应用程序的第一步是将Winsock.pbl加到应用程序中,然后声明如下全局变量:

  Winsock ws

  Boolean b—tcp—active

  //用于检验ws是否初始化成功

  PowerObject gpo—null//全局空对象

  在应用程序的Open事件加入下列代码:

  ws=Create Winsock

  //初始化Winsock的一个实例

  SetNull(gpo—null)//ws的函数中用到空对象gpo—null

  在应用程序的Close事件加入下列代码:



  图2

  Destroy ws//销毁ws对象

  完成以上工作后,就可以着手编程了,下面介绍如何利用Socket进行通信。

  1.用数据报式Socket向本机的7号端口发送数据

  TCP和UDP协议规定了传输层端口的长度为16比特,因此TCP和UDP软件可以使用216个不同的端口进行通信。尽管如此,编程时最好不要使用前1024个端口,因为这个范围内很多是专用端口,如21为FTP端口。本例中用到的7号端口很特殊,它回显接收到的任何数据,常用于端口检测。下面就向本机的7号端口发送数据报:

  DGSock=Create Socketdgram

  //创建数据报式Socket对象

  ulAddr=ws.inet—addr(″127.0.0.1″)

  //将本机IP地址转换为32位的ulong类型

  buf=Blob(″These data is send through datagram~r ~n″)//要发送的数据

  DGSock.sendto(buf,Len(buf),0,ulAddr,7)

  //向ulAddr主机的7号端发送数据报

  buf=Blob(Space(Len(buf)))

  //清空buf缓冲区

  DGSock.recv(buf,Len(buf),0)

  //接收数据报

  MessageBox(′Data Received′,String(buf))

  //显示接收到的数据

  DGSock.closesocket()//关闭Socket

  Destroy DGSock

  从上面的演示可以看出,发送到本机7号端口的数据报立即被反弹回来
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
在PB中使用VC++编制的DLL
  本文介绍了动态链接库的基本特点,给出了VC++建立DLL以及在PowerBuilder中调用VC++创建的DLL函数的编程实例,实现了通过DLL连接PowerBuilder和VC++编制的不同程序的目的。
  一、DLL概述:

  动态链接库(Dynamic-Link Library),简称DLL,是基于Windows程序设计的一个非常重要的组成部分。使用DLL有许多优点:

  (1)使用DLL的动态连接不是将库代码拷贝,只在程序中记录函数的入口点和接口,在程序执行时才将库代码装入内存,如果有多个程序使用相同的DLL,也只需将DLL在内存中装载一次,节省了内存开销。
  (2)DLL是基于Windows的程序模块,它不仅包含可执行代码,还可以包含数据,各种资源,扩大了库文件的使用范围。
  (3)对于一个大型的、不断更新的应用程序,可以将许多重复的功能写成DLL,用主程序调用,这样既减少了开发的工作量,又提高了访问速度。
  (4)DLL丰富了PowerScript语言的编程能力,可以使用PowerScript函数集之外的函数。例如:用户可能编写图象处理系统来浏览文件并将其存放于数据库,该应用需使用浏览器,但用PowerScript语言未提供做这类工作的函数,为了操纵设备,需要与设备本身环境通信,该环境一般是厂商提供的动态链接库。
  (5)DLL独立于编程语言,大多数WINDOWS编程环境都允许主程序调用DLL中的函数。即可以用VC++、VB、PowerBuilder、Delphi、汇编语言等建立DLL,然后在不同语言编制的应用程序中调用它。

  下面用一个实例说明通过DLL实现PowerBuilder程序和VC++程序之间的连接。

  二、 VC++创建DLL

  VC++5.0中可以用MFC AppWizard自动生成Win32 DLL和MFC AppWizard DLL,启动VC之后,从File | New菜单项,选择New对话框中的Projects标签,选择新项目为MFC AppWizard(dll),输入工程名pbdll,点击OK按钮,弹出图1-1所示对话框,选择DLL类型为:Regular DLL using shared MFC DLL,然后点击Finish按钮。这样,AppWizard将自动创建一个包含基本要素的DLL框架,接着手工添加代码。

  打开pbdll.cpp文件,添加如下函数:

extern "C" _declspec ( dllexport )
int PASCAL out_num(int x)
{
  int y;
  char msg[30];
  y=x > >2;
  sprintf(msg, "计算结果:%o ! ", y);
  ::MessageBox(NULL, msg, "信息", MB_OK);
  return 0;
}

  以上声明了函数out_num(),输入参数为一个整型数,作移位运算后,用对话框将计算结果显示出来。   接着打开pbdll.def文件,在EXPORTS下输入函数说明out_num,文件内容如下:

LIBRARY "pbdll"
DESCRIPTION 'pbdll Windows Dynamic Link Library'

EXPORTS
; Explicit exports can go here
  out_num @1


  最后编译生成动态链接库pbdll.dll。

  三、在PowerBuilder中调用VC++创建的DLL函数

  为了在PowerBuilder应用程序中调用存放在动态链接库pbdll.dll中的函数out_num(),需要事先声明。在声明时要明确:

  (1)函数的作用范围是全局的还是局部的。全局声明可使该函数用于整个应用,局部声明仅使该函数在对象的脚本中有效。
  (2)必须指明函数返回的数据类型、传递参数的个数和类型,并将存放该函数的动态链接库的名字告诉PowerBuilder。

  声明完成后,应用程序可以调用函数out_num() ,调用该函数的代码与调用任何标准的PowerScript函数一样,区别在于:该函数存放在动态链接库中,调用它时,动态链接库装入内存,函数执行。

  下面是PowerBuilder中被调用函数的使用声明:

  Function int out_num ( int irow ) LIBRARY "pbdll.dll"

  在PowerBuilder中调用函数out_num()代码如下:

int irow,retcode
irow=dw_1.rowcount()
retcode=out_num(irow)

  四、 加载DLL

  当PowerBuilder应用程序调用外部函数时,动态链接库装入内存。操作系统会在如下位置查找动态链接库:

  (1)EXE文件运行的目录。
  (2)Windows的系统目录。

  如果没有找到DLL,应用程序将产生运行错误,显示一个对话框,见图1-2(略)。如果找到DLL,它就被映射到程序的内存空间。

  五、 结束语

  DLL为不同编程环境下的应用程序之间的连接提供了方便,节省了内存,提高了速度,同时也丰富了PowerScript语言的编程能力。

liaolwj 2003-09-04
  • 打赏
  • 举报
回复
在PB中使用VC++编制的DLL
  本文介绍了动态链接库的基本特点,给出了VC++建立DLL以及在PowerBuilder中调用VC++创建的DLL函数的编程实例,实现了通过DLL连接PowerBuilder和VC++编制的不同程序的目的。
  一、DLL概述:

  动态链接库(Dynamic-Link Library),简称DLL,是基于Windows程序设计的一个非常重要的组成部分。使用DLL有许多优点:

  (1)使用DLL的动态连接不是将库代码拷贝,只在程序中记录函数的入口点和接口,在程序执行时才将库代码装入内存,如果有多个程序使用相同的DLL,也只需将DLL在内存中装载一次,节省了内存开销。
  (2)DLL是基于Windows的程序模块,它不仅包含可执行代码,还可以包含数据,各种资源,扩大了库文件的使用范围。
  (3)对于一个大型的、不断更新的应用程序,可以将许多重复的功能写成DLL,用主程序调用,这样既减少了开发的工作量,又提高了访问速度。
  (4)DLL丰富了PowerScript语言的编程能力,可以使用PowerScript函数集之外的函数。例如:用户可能编写图象处理系统来浏览文件并将其存放于数据库,该应用需使用浏览器,但用PowerScript语言未提供做这类工作的函数,为了操纵设备,需要与设备本身环境通信,该环境一般是厂商提供的动态链接库。
  (5)DLL独立于编程语言,大多数WINDOWS编程环境都允许主程序调用DLL中的函数。即可以用VC++、VB、PowerBuilder、Delphi、汇编语言等建立DLL,然后在不同语言编制的应用程序中调用它。

  下面用一个实例说明通过DLL实现PowerBuilder程序和VC++程序之间的连接。

  二、 VC++创建DLL

  VC++5.0中可以用MFC AppWizard自动生成Win32 DLL和MFC AppWizard DLL,启动VC之后,从File | New菜单项,选择New对话框中的Projects标签,选择新项目为MFC AppWizard(dll),输入工程名pbdll,点击OK按钮,弹出图1-1所示对话框,选择DLL类型为:Regular DLL using shared MFC DLL,然后点击Finish按钮。这样,AppWizard将自动创建一个包含基本要素的DLL框架,接着手工添加代码。

  打开pbdll.cpp文件,添加如下函数:

extern "C" _declspec ( dllexport )
int PASCAL out_num(int x)
{
  int y;
  char msg[30];
  y=x > >2;
  sprintf(msg, "计算结果:%o ! ", y);
  ::MessageBox(NULL, msg, "信息", MB_OK);
  return 0;
}

  以上声明了函数out_num(),输入参数为一个整型数,作移位运算后,用对话框将计算结果显示出来。   接着打开pbdll.def文件,在EXPORTS下输入函数说明out_num,文件内容如下:

LIBRARY "pbdll"
DESCRIPTION 'pbdll Windows Dynamic Link Library'

EXPORTS
; Explicit exports can go here
  out_num @1


  最后编译生成动态链接库pbdll.dll。

  三、在PowerBuilder中调用VC++创建的DLL函数

  为了在PowerBuilder应用程序中调用存放在动态链接库pbdll.dll中的函数out_num(),需要事先声明。在声明时要明确:

  (1)函数的作用范围是全局的还是局部的。全局声明可使该函数用于整个应用,局部声明仅使该函数在对象的脚本中有效。
  (2)必须指明函数返回的数据类型、传递参数的个数和类型,并将存放该函数的动态链接库的名字告诉PowerBuilder。

  声明完成后,应用程序可以调用函数out_num() ,调用该函数的代码与调用任何标准的PowerScript函数一样,区别在于:该函数存放在动态链接库中,调用它时,动态链接库装入内存,函数执行。

  下面是PowerBuilder中被调用函数的使用声明:

  Function int out_num ( int irow ) LIBRARY "pbdll.dll"

  在PowerBuilder中调用函数out_num()代码如下:

int irow,retcode
irow=dw_1.rowcount()
retcode=out_num(irow)

  四、 加载DLL

  当PowerBuilder应用程序调用外部函数时,动态链接库装入内存。操作系统会在如下位置查找动态链接库:

  (1)EXE文件运行的目录。
  (2)Windows的系统目录。

  如果没有找到DLL,应用程序将产生运行错误,显示一个对话框,见图1-2(略)。如果找到DLL,它就被映射到程序的内存空间。

  五、 结束语

  DLL为不同编程环境下的应用程序之间的连接提供了方便,节省了内存,提高了速度,同时也丰富了PowerScript语言的编程能力。

thelazyman 2003-09-04
  • 打赏
  • 举报
回复
To:liaolwj (风儿)
你提供的资料不错,有参考价值,给我发一份吧
thelazyman@163.com

先谢了!!
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
那就再来一篇:
用PB5设计串口通讯程序

  PowerBuilder5.0是一种面向对象的、具有可视图形界面的、快速的交互式开发工具,它通过不同数据库采用各自的专用接口或通过ODBC接口,同时支持多种关系数据库系统、支持多文档界面(MDI)、对象嵌入 与链接(OLE)、动态数据交换(DDE)。利用其独特的数据窗口对象,无须编写SQL语句,便可直接对数据库进行查询、修改、插入、删除、浏览、打印,以多种文件格式打开和存储数据,因此深受广大用户的欢迎。在实际应用过程中经常遇到PowerBuilder与其它设备通过串口进行通讯的程序设计如IC卡应用系统中需通过串口与IC卡读写器进行通讯;在控制系统中,需通过串口与下位机进行通讯。下面介绍PowerBuilder5.0中常用的两种串口通讯设计方法。

  一、 调用Windows SDK函数进行串口通讯

  1、Windows SDK函数介绍

  OpenComm int OpenComm(LpszDevControl, CbInQueue,cbOutQueue)LPCSTR lpszdevcontro l 设备控制信息的地址 UINT CbInQueue 接受队列的大小(以字节为单位) UINT cbOutQueue 发送队列的大小返回:如调用成功,返回值标示此打开的设备否则其返回值小于0

  ·CloseComm Int CloseComm(idComDev)
  Int idComDey 要关闭的设备 返回值:调用成功返回0,否则返回负值

  ·WriteComm int WriteComm(idComDev,lpvBuf,cbWrite)
  int idComDev 通讯设备标示符 const void FAR * lpvBuf 数据缓存区地址 int ,cbWrite 要写的长度返回值:如果成功返回所写的字节数,否则返回值小于0

  ·ReadComm Int ReadComm(idComDev,lpvBuf,cbRead)
  int idComDev 通讯设备标示符 const void FAR * lpvBuf 数据缓存区地址 int cbRead 要读的字节数返回值:如果成功返回所读的字节数,否则返回值小于0

  ·FlushComm Int FluseComm(idComDev,fnQueue)
  Int idComDev 通讯设备标示符 Int fnQueue 要刷新的队列 返回值:成功时返回0,否则返回为负

  2、示例:

  为一人事管理系统中的查询窗口。如果想与被查询人拨打电话,可输入该人姓名,在输入过程中,数据窗口会显示满足要求的所有人姓名,双击该行即将该人电话号码显示于单行编辑窗内,然后按“拨号”按钮即可。

  程序设计如下:

  在窗口设计菜单中选取:Declare菜单?Declare External Function 输入:
Function int OpenComm(String Comm, Uint Inqueue,Uint Outqueue)Library “USER.EXE”
Function int CloseComm(int lpt)Library “USER.EXE”
Function int WriteComm(int lpt,String buf,int Size) Library “USER.EXE”
Function int FlushComm(int lpt, int no_que)Library “USER.EXE”
“拨号”按钮的”Clicked” 事件编程如下:
int ret String port_2,ph_code port_2=”Com2” //取单行编辑框内容,并用atdt拨号
ph_code=”atdt”+sle_code+”~r~n” //打开串口
ret=OpenComm(port_2,128,128) //拨号开始
FlushComm(ret,0)
FlushComm(ret,1)
WriteComm(ret,ph_code,len(ph_code))
WriteComm(ret,”~r~n”,2)
CloseComm(ret)

  二、利用Microsoft公司提供的通讯控件

  利用Microsoft公司提供的通讯控件(Mscomm.vbx,用于16位通讯程序、Mscomm32.ocx用于开发32位通讯程序)可方便实现串口通讯

  1、 常用属性 CommPort:设置或返回串行端口号,缺省为1。


Setting:设置或返回串行端的波特率、奇偶校验位、 数据位数、停止位。缺省值为"9600,N,8,1"。
PortOpen:设置它为True则打开端口,设置它为False则关闭端口。
InBufferSize:设置或返回接收缓冲区的大小,缺省为1024 字 节。
InBufferCount:返回接收缓冲区内的等代读取的字节个数,设属性为0清除接收缓冲区。
OutBufferSize:设置或返回发送缓冲区,缺省为512字节。
OutBufferCounter:返回发送缓冲区内等待发送的字符数,可用0来清空缓冲区。
Output:向发送缓冲区传送数据
RThreshold: 该属性确定当接收缓冲区内字节个数达或超过该值后就产生代码为ComEventReceive
的OnComm事件,设置位0,则不产生OnComm事件。
CommEvent:有通讯错误或事件发生时产生OnComm事件,CommEvent事件的值可以用来确定引
发OnComm事件的具体的错误或事件常用的有以下几种(更详细的资料可参考MSComm控件帮助文件)
ComEventbreak:接受到中断信号
ComEventFrame:硬件检测到帧错误。
ComEventRxOver:接收缓冲区溢出。
ComEventTxFull:发送缓冲区溢出。
ComEventReceive:接受到规定的字符数。
InputLen:设置或返回接收缓冲区内用Input读入的个数。若取0,则读取整个缓冲区的内容。
Input:返回并删除接受缓冲区的数据。

  2、 示例:

  下面举一接收程序示例:制作一通讯接收窗口,选择菜单Controls→OLE→Insert Control→Microsoft Communications Control,

  在窗口中出现通信控件图标单击鼠标右键,选择OCX Properties设置常用属性,也可在程序中进行设置窗口的Open事件程序如下:

ole_1.object.CommPort=2
ole_1.object.Settings="9600,N,8,1"
ole_1.object.PortOpen=ture
ole_1.object.Rthreshold=10
ole_1.object..Inputlen=0 . .
通信控件的oncomm事件的程序如下
choose case ole_1.object.CommEvent
case comEventBreak //接收到中断信号
case comEventCDTO //处理CD超时
. . .
case comEvReceive sle_1.text=ole_1.object.Input
. .
end choose

  以上是一个基本的例子,在实际应用过程中应根据不同的情况进行不同的设计,如波特率、帧格式等。

  总之,利用以上方法可以方便的在PowerBuilder中进行串口通讯,并对接收的数据利用PowerBuilder进行数据处理。

workhand 2003-09-04
  • 打赏
  • 举报
回复
继续阿,很好。
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
2.1.6用户界面
用户界面主要存在于客户端程序中,主要是用于与用户的交互。客户端程序通过用户界面接收用户的请求,执行相应的操作,然后将结果通过用户界面以一定方式展示给用户。

第二节 PowerBuilder中分布式应用的实现
本节的主要内容是介绍怎样来建立应用服务器应用,以及怎样将客户端程序连接到应用服务器上。
2.2.1应用服务器的实现
1. 定义一服务器接口全局对象
TransPort g_Server
2. 设置好服务器接口对象的属性
g_Server = CREATE TRANSPORT
g_Server.Driver = “WINSOCK” //使用的协议
g_Server.Application = “9988” //服务器端口号
详细属性说明请见PowerBuilder中的帮助 TRANSPORT OBJECT
3. 调用服务器接口对象的函数,运行应用服务器
if 0 <> g_Server.Listen() then
//failuer
else
//success
end if
4. 在应用服务器退出之前,调用服务器接口对象的函数,退出应用服务器监听程序
g_Server.StopListening()
DESTROY g_Server
2.2.2客户端程序实现
1. 定义一connection类型的变量(客户端连接对象):
CONNECTION g_connection
2. 设置好客户端连接对象的各项属性:
g_connection.Driver = “WINSOCK”
g_connection.Location = “主机名” //服务器域名或IP地址
g_connection.Application = “9988” //服务器端口号
3. 调用成员函数,连接应用服务器:
g_connection.ConnectToServer()
4. 在使用完成后,断开与应用服务器的连接:
g_connection.DisconnectServer()

第三节 远程对象及代理
上节我们详细介绍了怎样建立应用服务器程序和客户端程序,以及怎样将客户端连接到应用服务器上,但是应用服务器可以提供什么样的服务呢?客户端程序又是怎样去调用应用服务器提供的服务的呢?这就是我们这节要解决的问题。
2.3.1应用服务器可以提供的服务
应用服务器可以提供的服务就是远程对象。我们先来明确一个问题,在PowerBuilder中,到底什么是远程对象呢?简单的说,远程对象就是一种不可视的用户自定义对象,所有其提供的声名为公有的函数和成员变量都可以被客户端程序调用和访问。出于显而易见的原因,远程对象与一般的不可视用户对象相比,还要遵循以下规则:
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
第二章 使用PowerBuilder编写分布式应用系统入门

第一节 总体介绍
在PowerBuilder的分布式应用系统的实现中,其结构图如下:









图2.1 PowerBuilder中分布式应用结构示意图
从上图我们可以看出,分布式应用主要由数据库服务器、应用服务器(远程对象、服务器接口)和客户端程序(远程对象代理、客户端接口、用户界面)组成,下面我们将分别介绍各部份。
2.1.1数据库服务器。
数据库服务器的主要工作是进行数据的管理工作,包括数据库、数据存储过程、触发器等等其它数据库对象。目前流行的数据库服务器管理系统主要有ORACLE,MS SQL SERVER,SYBASE SQL SERVER等大中型数据库,以及SYBASE ANYWHERE,DBF,BTRIEVE等小型及桌面型数据库。
2.1.2 远程对象
远程对象指的是存在于应用服务器中,供客户端程序调用的对象;其功能由编写者确定。客户端程序通过网络调用应用服务器上的远程对象的功能来实现它自已的功能;远程对象负责与数据库服务器进行通迅,取得数据,并将数据传递给客户端程序。
2.1.3服务器接口
服务器接口的主要功能是负责应用服务器与客户端的网络通迅工作,编写者在设置好相应的网络特性如使用的协议和服务器端口号等其它特性后,启动服务器接口,监听客户端对服务器的请求,并通过远程对象执行请求,然后将结果发送给客户端应用程序。
2.1.4客户端接口
客户端接口的功能主要是负责客户端程序与服务器接口之间的网络通迅工作,客户端程序通过客户端接口与应用服务器相连,并发送请求到应用服务器,然后接收结果。
2.1.5远程对象代理
远程对象代理实际上就是远程对象的一个定义,客户端程序通过此代理来正确的对应用服务器发送请求并正确的接收返回结果。即客户端程序通过远程对象代理来获知应用服务器上所提供的服务的类型,从而正确使用应用服务器。
liaolwj 2003-09-04
  • 打赏
  • 举报
回复
第一章 什么是分布式计算体系
什么是分布式计算体系?所谓分布式计算,指的是在一个事务过程中,整个事务的处理分布到多个实体上来完成(在计算机网络中即多台计算机),与传统的集中处理方式不同。所谓分布式计算体系,指的是一个使用分布式计算的方法来设计、编写和运行的应用系统。就其本质上来说,它是和面向对象编程一样,指的是一种程序设计和软件发布的方式,而与具体的语言和编译器无关。
分布式计算体系从概念上来说,基本上可以分为以下几个部份:
1. 数据库服务器:数据库服务负责有关数据库的管理工作,包括数据库的建立,数据的组织和查询,对数据进行统计等等与数据操作有关的功能。
2. 客户程序:客户程序主要实现与用户进行交互的功能,从用户收集信息和命令,反馈给系统;从系统得到数据和结果,通过显示或打印机等其它输出设备,反馈给用户。
3. 应用服务器:应用服务器是数据库服务与客户程序之间的桥梁,客户程序通过应用服务器向数据库服务器发送命令、请求数据,数据库服务器通过应用服务器响应命令、返回数据。应用服力器在此过程中对所有的命令和数据进行控制,以实现商业逻辑。
我们可以通过以下的图示来对分布式计算体系有一个更直观的了解:








图1.1 分布式计算体系工作流示意图
说明:在这个体系结构中,前台程序并不直接同数据库服务器打交道,而是间接从应用服务器来获取数据

与传统的C/S结构体系相比,使用分布式计算体系来编写您的应用程序,能够得到什么好处呢?
1. 分布式计算体系更安全可靠。首先,客户端不和数据库服务器直接相连,甚至可以不在同一物理网络上,充分保证了数据的安全性,保证用户只能通过客户端应用程序来存取数据;其次,只要系统设置有相应权限管理,用户就只能进行与其权限相符的操作,从而进一步保证系统数据的安全性;第三,应用服务器的分布,使得相应的商业逻辑的实面由不同的人员管理,使系统更具安全性。
2. 分布式计算体系对客户端的要求更低,可以充分发挥服务器的能力。所有的商业逻辑的实现,都在应用服务器和数据库服务器上实现了,并且,大量的统计和计算工作都是在服务器上完成,这样的话,可以充分发挥服务器的能力,并且客户端所要做的工作就只是与用户进行交互,而不要进行大量的计算工作,对客户端的要求比较低。
3. 使用分布式计算体系,可以很轻易的实现系统的无缝升级。如果商业逻辑变化了,只要对应用服务器进行修改和升级,而不要到用户那去升级其客户端程序,更方便快捷、省时省力。

1,108

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧