网页功能: 加入收藏 设为首页 网站搜索  
TAPI笔记
发表日期:2003-08-11作者:[] 出处:  

一.前言

数据通讯的重要性是不言而喻的,特别是在写程序的过程中掌握数据通讯技术,了解各种通讯的方法及其优缺点是很重要的。调制解调器是目前进行远程通讯的一种重要工具,基于调制解调器的应用越来越多,TAPI就是Microsoft及Intel公司联合开发的,基于MODEM,电话线进行数据传输的一种应用程序接口,TAPI既适用于BC++也适用于VC++。

近一段时间我一直使用TAPI实现两台机器间用MODEM,电话线之间进行数据传输,现总结如下:

  Windows95/98基于API的通信手段大致分为以下几种:

1. 基于TCP/IP协议的WinSock API,可实现局域网上或互联网上的微机通信;

2. 基于进程之间的通信技术:动态数据交换(DDE);

3. 基于直接电缆连接的通信技术,可直接操作串行口、交行口以及远红外线接口;

4. 基于电话线路的通信应用程序接口(TAPI),可方便地控制调制解调器。

二.通讯过程

  TAPI的基本通讯过程包括如下几步:

步骤

说明

初始化TAPI环境

使用lineInitialize函数初始化TAPI32.DLL,获得TAPI句柄。此时必须指定一个回调函数,由此回调函数处理消息。

应答方初始化

1.  通过lineNegotiateAPIVersion确定使用TAPI的版本;

2.  用lineOpen打开线路,得到HLINE句柄,dwPrivileges函数必须使用LINECALLPRIVILEGE_MONITOR+LINECALLPRIVILEGE_OWNER,与呼叫方不同;

呼叫方进行呼叫

1.  通过lineNegotiateAPIVersion确定使用TAPI的版本;

2.  用lineOpen打开线路,得到HLINE句柄,dwPrivileges函数必须使用LINECALLPRIVILEGE_NONE;

3.  创建拨号参数,类型为:LPLINECALLPARAMS;

4.  用lineMakeCall或lineDial进行拨号,两者的区别是,使用前者是还没有HCALL句柄的情况下,使用此拨号可得到HCALL句柄,而lineDial是在HCALL句柄已得到的情况下使用。

回调函数的处理

回调函数对消息进行处理,最主要的消息包括:

1.  LINECALLSTATE_OFFERING:此函数由应答方捕获,得到此消息表明已接收到拨号方的呼叫,应进行回应,回应的格式为:lineAnswer( (HCALL)dwDevice,NULL,0 );

2.  LINECALLSTATE_BUSY, LINECALLSTATE_IDLE, LINECALLSTATE_SPECIALINFO:在拨号或应答过程中出现错误,应断接;

3.  LINECALLSTATE_DISCONNECTED:某一方断接,此时可以判断到底是哪一种原因造成断接,同时也应调用断接函数;

4.  LINECALLSTATE_CONNECTED:已连接上并建立线路,此时应调用lineGetID函数得到MODEM的句柄,必要时应清空MODEM缓冲区,以便开始进行数据的传输。

断接

1.  任何一方可以调用linDrop(HCALL)来停止呼叫,该函数将会发送LINECALLSTATE_IDLE消息给回调函数

2.  当任何一方收到LINECALLSTATE_IDLE消息时应调用lineDeallocateCall(hCall)来释放掉占用的呼叫资源;

3.  当收到LINECALLSTATE_DISCONNECTED 消息时应使用lineClose(HLINE)释放由lineOpen 分配的资源,调用lineShutDown(HLINEAPP)释放为线路设备分配的资源

数据的发送与接收

使用ReadFile与WriteFile函数发送与接收数据,共中的文件句柄好是MODEM句柄。

三.数据发送与传输

ReadFile与WriteFile并非TAPI的函数集成员函数,TAPI并不提供数据传输的函数。

(一)函数调用格式:

ReadFile的调用格式为:

ReadFile(文件句柄,发送的数据的缓冲区地址,欲发送多少字节数据,实际发送了多少字节数据,一个指向OVERLAPPED结构的指针);

1. 文件句柄:此处即为MODEM句柄;

2. 发送数据的缓冲区地址:可为char *或LPDWORD格式,传送的数据为二进制格式;

3. 欲发送多少字节数据:用户指定,但也可以使用ClearCommError函数来测到当前MODEM缓冲区有多少字节数据,然后有多少读多少。

4. 实际发送了多少字节数据:返回值;

5. OVERLAPPED结构的指针:

(二)传输模式

在95/98下:ReadFile与WriteFile有两种模式,一种是等待模式,一种是非等待模式。

等待模式的格式为:

DWORD len;

ReadFile(g_hCommFile,lpBuffer,256,&len,NULL);

此时必须完成了读写操作函数才会返回,实际读写的字节数在len中,最后一个参数必须为NULL。

非等待模式的格式为:

OVERLAPPED myOVLP = {0, 0, 0, 0, NULL};

myOVLP.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

ReadFile(g_hCommFile,lpBuffer,256,NULL,&myOVLP);

GetOverlappedResult(g_hCommFile,&myOVLP,&len,TRUE)

CloseHandle(myOVLP.hEvent);

此时ReadFile函数会马上返回,第四个参数会被忽略,实际读写的字节数由GetOverlappedResult函数返回,如果读写成功,此函数为返回非0值,最后一个函数为TRUE,表示等待方式,为FALSE表示非等待。

在NT下必须使用OVERLAPPED参数,调用格式与95/98下的非等待方式类似。

(三)如何保证数据传输的正确性

在等待模式下,如果读写操作不完成,函数就会一直处于挂起状态;

在非等待模式下,函数调用后会马上返回,此时应调用GetOverlappedResult函数来判断,如果此函数返回FALSE,就应进一步判断,例如:

WriteFile(g_hCommFile,lpBuffer,256,NULL,&myOVLP);

while(!GetOverlappedResult(g_hCommFile,&myOVLP,&len,TRUE))

{

 dwError=GetLastError();

 if(dwError == ERROR_IO_INCOMPLETE)

   continue;

 else

   出错;

}

  

(四)如何提高传输性能

因为MODEM的缓冲区毕竟非常有限,如果某一方出现阻塞,另一方就不得不陷入等待之中,而且双方之间的协调会使速率非常之低,此时可以采用缓冲区的办法,发送与接收双方都开辟一个缓冲区(应是循环的),数据直接写入缓冲区中,然后用线程的方法,发送方不断的判断缓冲区中是否有数据,如果有发送方就发送到MODEM中,接收方则不断判断MODEM中是否有数据,如果有就读入缓冲区中。

就MODEM传输速度,我使用的环境是内线,没有通过交换机,满载的情况下每秒在6K字节/秒左右。

四.消息的处理

TAPI由回调函数进行消息处理,回调函数在初始化TAPI时创建,消息的处理在TAPI的使用过程中是至关重要的。以下是一些主要的消息:

1.   LINECALLSTATE_IDLE

没有呼叫,为空,此时应断接,释放掉占用的资源;

2.   LINECALLSTATE_BUSY

线路忙或设备忙,此时应断接,释放掉占用的资源;

3.   LINECALLSTATE_SPECIALINFO

特别的消息,此时应断接,释放掉占用的资源;

4.   LINECALLSTATE_OFFERING

应答方已收到呼叫方信号,此时应进行应答,调用lineAnswer函数;

5.   LINECALLSTATE_CONNECTED

已连接成功,此时可进行数据的传输,但必须先得到MODEM的句柄;

6.   LINECALLSTATE_DISCONNECTED

已断接,此时应释放掉占用的资源。

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 TAPI笔记
本类热点文章
  shell函数能以同步方式打开一个exe文件
  shell函数能以同步方式打开一个exe文件
  揭穿号称内存占用极低的软件的诡计
  读写INI文件的四个函数
  用VB6实现真正实用的多线程处理
  VB的API编程精粹
  VB的API编程精粹
  TAPI笔记
  TAPI笔记
  巧用API函数增强VB位操作功能
  锁定计算机
  锁定计算机
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00382