首页 新闻 工控搜 论坛 厂商论坛 产品 方案 厂商 人才 文摘 下载 展览
中华工控网首页
  P L C | 变频器与传动 | 传感器 | 现场检测仪表 | 工控软件 | 人机界面 | 运动控制
  D C S | 工业以太网 | 现场总线 | 显示调节仪表 | 数据采集 | 数传测控 | 工业安全
  电 源 | 嵌入式系统 | PC based | 机柜箱体壳体 | 低压电器 | 机器视觉
基于WinTAPI的调制解调器编程
中华工控网
收藏本文     查看收藏
基 于Win95 TAPI 的 调 制 解 调 器 编 程 <BR> 谭 安 平----中 国 科 学 院 近 代 物 理 研 究 所( 7 3 0 0 0 0) <BR> 一、 简 介:<BR> ---- 随 着Win95 操 作 系 统 的 普 及, 计 算 机 之 间 的 通 信 已 经 成 为 大 多 数 应 用 程 序 开 发 的 要 求, 这 其 中 的 主 要 原 因 是Win95 不 仅 仅 能 够 支 持 大 多 数 硬 件, 而 且 为 硬 件 的 操 作 提 供 了 方 便 的 编 程 接 口(API),Win95 的 应 用 程 序 接 口(API) 提 供 的 通 信 手 段 大 致 分 为 以 下 几 类: 1 基 于TCP/IP 协 议 的Winsock API, 可 实 现 局 域 网 上 或 互 联 网 上 的 微 机 通 信; 2 基 于 进 程 之 间 的 通 信 技 术: 动 态 数 据 交 换( D D E); 3 基 于 直 接 电 缆 连 接 的 通 信 技 术, 可 直 接 操 作 串 行 口、 并 行 口 以 及 远 红 外 线 接 口; 4 基 于 电 话 线 路 的 通 信 应 用 程 序 接 口( T A P I/Telephony API), 可 方 便 地 控 制 调 制 解 调 器; 从 目 前 的 发 展 状 况 看 来, 调 制 解 调 器 已 经 成 为 远 距 离 通 信 的 一 种 重 要 工 具, 为 此Microsoft 及Intel 公 司 联 合 开 发 了TAPI 这 样 一 个 编 程 接 口, 而 且, 使 用API 函 数 编 制 的 程 序 段 既 适 用 于Borland C++ 编 译 器, 同 时 也 能 插 入Visual C++ 程 序 中 编 译 运 行, 作 为Win95 的 应 用 程 序 编 制 人 员, 学 会 使 用TAPI 编 程 操 作 调 制 解 调 器 通 过 电 话 线 路 进 行 通 信 这 一 技 术 是 很 有 必 要 的。 下 面 就TAPI 编 程 进 行 讨 论: </P><P> 二、 通 信 过 程 描 述<BR> ---- 1 初 始 化 线 路( 通 信 双 方 都 应 该 初 始 化 线 路) <BR> ---- 通 过 使 用lineInitialize 函 数 初 始 化TAPI.DLL 得 到TAPI 使 用 句 柄 的 指 针hTapi, 请 注 意 参 数 中 回 调 函 数 的 定 义( 所 有 提 及 函 数 的 用 法 均 可 从BC++5.0 及Visual C++5.0 的 帮 助 中 获 得); 通 过 调 用lineOpen 函 数( 用 到 参 数hTapi) 获 得 线 路 句 柄hLine; 再 利 用lineGetID( 用 到 参 数hLine) 获 取 调 制 解 调 器 句 柄hModem </P><P> ---- 2 配 置 线 路( 可 选) </P><P> ---- </P><P> ---- 调 用SetCommConfig( 用 到hModem) 改 变 调 制 解 调 器 的 设 置 </P><P> ---- 3 拨 号( 由 呼 叫 方 执 行) </P><P> ---- 使 用lineMakeCall 函 数( 用 到hLine) 进 行 拨 号, 完 成 后 获 得 呼 叫 句 柄hCall( 呼 叫 方 的 呼 叫 句 柄) </P><P> ---- 4 应 答 链 接( 由 被 呼 叫 方 执 行) </P><P> ---- 被 呼 叫 的 一 方 的 回 调 函 数 得 到LINECALLSTATE_OFFERING 消 息 时, 调 用lineAnswer 函 数 实 现 自 动 应 答( 呼 叫 句 柄hCall 由 回 调 函 数 的 参 数 给 出) </P><P> ---- 5 数 据 通 信( 双 方) </P><P> ---- 当 回 调 函 数 收 到LINECALLSTATE_CONNECTED 消 息 后, 请 先 清 除 接 收 缓 冲 区, 可 以 使 用 函 数 为WriteFile 及ReadFile 函 数 进 行 数 据 交 换, 注 意 参 数hFile 为 调 制 解 调 器 句 柄hModem </P><P> ---- 6 挂 机( 某 一 方) </P><P> ---- 通 信 完 毕 任 何 一 方 都 可 以 调 用 函 数lineDrop(hCall,NULL,0) 来 停 止 呼 叫, 该 函 数 还 发 送LINECALLSTATE_IDLE 消 息 给 回 调 函 数 </P><P> ---- 7 关 闭 线 路( 双 方) </P><P> ---- 通 信 双 方 的 回 调 函 数 在 收 到LINECALLSTATE_IDLE 消 息 时 都 应 该 调 用 函 数lineDeallocateCall(hCall) 释 放 相 应 呼 叫 占 用 的 资 源; 当 回 调 函 数 收 到LINECALLSTATE_DISCONNECTED 消 息 时 请 使 用lineClose(hLine) 释 放 由lineOpen 分 配 的 资 源, 调 用lineShutDown(hTapi) 释 放 为 线 路 设 备 分 配 的 资 源 </P><P> 三、 软 硬 件 环 境<BR> ---- 下 图 示 意 出 了 我 们 的 应 用 程 序 所 处 的 位 置 以 及 涉 及 到 的 软 硬 件 环 境: <BR> ---- 我 们 的 通 信 应 用 程 序 通 过TAPI 操 作Modem 拨 号、 应 答、 链 接、 挂 机 控 制 电 话 呼 叫, 在 编 制DOS 应 用 程 序 的 时 候, 我 们 经 常 使 用Hayes 兼 容 的AT 命 令 集 来 完 成 这 些 操 作, 由 于 各 调 制 解 调 器 厂 家 对 该 命 令 集 都 做 了 各 自 的 扩 展, 因 而, 我 们 的DOS 应 用 程 序 一 般 只 能 操 作 一 小 部 分 调 制 解 调 器, 而 各 厂 家 都 提 供Windows 驱 动 程 序, 所 以, 使 用TAPI 编 制 的 应 用 程 序 能 够 操 作 绝 大 多 数 调 制 解 调 器; 图 中 的 通 信API 是 应 用 程 序 发 送、 接 收 数 据 的 编 程 接 口。 </P><P> 四、 程 序 流 程 结 构 框 图<BR> ---- 由 于Win95 为 多 任 务 操 作 系 统, 我 们 的 流 程 图 只 能 代 表 本 应 用 程 序 的 执 行 先 后 关 系, 程 序 中 的 等 待 及 检 测 实 际 上 是 等 待Win95 提 供 的 消 息, 所 以 并 不 占 用CPU 时 间, 在 下 面 的 程 序 中 可 以 看 出。 另 外, 数 据 交 换 的 协 议 可 由 自 己 制 定, 也 可 使 用 已 有 的 协 议。 <BR> 五、 软 件 编 制<BR> ---- 由 于Windows 编 程 的 框 架 基 本 相 同, 在 此 我 们 只 介 绍 涉 及 到 通 信 的 一 部 分 源 程 序: <BR> ---- 1 头 文 件 中 应 该 包 括: </P><P> ---- #include < tapi.h > </P><P> ---- 请 注 意 工 程 文 件 的 属 性 应 该 是Windows 32 位 应 用 程 序 </P><P> ---- 2 通 信 所 涉 及 到 的 一 些 全 局 变 量 定 义 及 类 型 定 义: </P><P> char RecBuf[20],buf[20]// 缓 冲 区<BR> DWORD Error; // 错 误 码<BR> COMSTAT Status; // 状 态 码<BR> DWORD NumLine; // 允 许 使 用 的 线 路 设 备 数<BR> LINECALLPARAMS para;// 呼 叫 参 数<BR> TmyDecFrame * pwin=NULL;// 主 窗 口 指 针<BR> HLINEAPP myhTapi;// 线 路 应 用 程 序 句 柄<BR> HLINE myhLine;// 线 路 句 柄<BR> HANDLE myhModem;// 调 制 解 调 器 句 柄<BR> HCALL myhCall;// 呼 叫 句 柄</P><P> typedef struct tagModemID{<BR>   HANDLE hModem;<BR>   char ModemName[1];<BR> }ModemID;</P><P> ---- 3 下 面 为 获 取 调 制 解 调 器 句 柄 的 函 数 定 义 </P><P> ---- 因 为 每 个 调 制 解 调 器 的 标 志 字 符 串 长 度 不 一, 所 以 函 数 中 用 到 了 可 变 长 度 的 字 符 串, 处 理 方 法 是 先 为 字 符 串 指 针 分 配sizeof(VARSTRING) 大 小 的 空 间, 再 利 用 该 空 间 容 纳 调 用LineGetID 时Windows 返 回 的 信 息, 根 据 返 回 信 息 判 断 所 需 空 间 大 小 重 新 分 配 空 间, 再 次 调 用LineGetID 就 可 以 取 得 完 整 的 标 志 字 符 串。 </P><P> void GethModem(HLINE hLine)<BR> {  ModemID far *mid;<BR>    VARSTRING * str;<BR>    LONG lid;<BR>   DWORD size;<BR>    char mark=1;<BR>  <BR>    str=(VARSTRING *)malloc(sizeof(VARSTRING));<BR>    if(!str) <BR> return NULL;<BR>   str- >dwTotalSize=sizeof(VARSTRING);<BR>    do<BR>    { if((lineGetID(myhLine,0,NULL,LINECALLSELECT_LINE,str,<BR> "comm/datamodem")==0)&&(str- >dwTotalSize < str- > dwNeededSize))<BR>    { dwSize=str- >dwNeededSize;<BR>       free(str);<BR>      str=(VARSTRING *)malloc(dwSize);<BR>    if(!str)<BR>       { myhModem=NULL;<BR>      mark=2;<BR> }<BR> str- >dwTotalSize=dwSize;<BR>    }<BR>    else mark=0;<BR>  }while(mark==1);<BR>    if(mark==0)<BR>    { mid=(ModemID far *)((LPSTR)str+str- >dwStringOffset);<BR>     myhModem=mid- >hModem;<BR>    }<BR>    free(str);<BR> }</P><P> ---- 4 在 主 窗 口 初 始 化 函 数 中 加 入 对 线 路 的 初 始 化 过 程: </P><P> pwin=this;// 获 得 主 窗 口 指 针<BR>  while(lineInitialize(&myhTAPI,GetModule()- >GetInstance(),<BR>    (LINECALLBACK)MakeProcInstance((FARPROC) lpfnCallback,<BR>  GetModule()- >GetInstance()), "TRY",&NumLine )==LINEERR_REINIT)<BR>  { sleep(1);// 延 迟  };<BR>  Error=lineOpen(hTAPI,0,&HLine,0x10004,0,0,LINECALLPRIVILEGE_MONITOR+<BR> LINECALLPRIVILEGE_OWNER,LINEMEDIAMODE_DATAMODEM,NULL);<BR>   if(Error!=0)<BR>   { sprintf(buf,"%lx",Error);<BR> MessageBox(buf,0,MB_OK); }<BR>   else<BR>   { GethModem(myhLine);// 取 得myhModem 的 值<BR>    if(myhModem!=NULL)<BR>    {  para.dwBearerMode=LINEBEARERMODE_VOICE;<BR>  para.dwMediaMode=LINEMEDIAMODE_DATAMODEM;<BR>   para.dwTotalSize=sizeof(LINECALLPARAMS);<BR>     Error=lineMakeCall(myhLine,&myhCall,"8880751",0,¶);<BR>     If(Error!=0)<BR>     { sprintf(buf,"%lx",Error);<BR>      MessageBox(buf,0,MB_OK); }<BR>    }<BR>   }<BR>  }</P><P> ---- 5 呼 叫 方 回 调 函 数 的 定 义 </P><P> void far pascal TMyDecFrame::lpfnCallback<BR> (DWORD hDevice, DWORD dwMsg,<BR> DWORD dwCallbackInstance, <BR> DWORD dwParam1, DWORD dwParam2,<BR> DWORD dwParam3)// <BR> 参数定义同lineCallbackFunc函数中的参数定义<BR> {  int Rec_num=0;</P><P>  switch(dwParam1)<BR>  { case LINECALLSTATE_CONNECTED:<BR> DWORD len;<BR>    ClearCommError(myhModem,&Error,&Status);<BR>  Rec_num=Status.cbInQue;<BR>    ReadFile(myhModem,RecBuf,Rec_num,&len,0);<BR> //至此已经为数据通信做好了前期准备,可设立标志<BR>   WriteFile(myhModem,"Success",7,&len,0);<BR>    ReadFile(myhModem,RecBuf,8,&len,0);<BR>    pwin->MessageBox(RecBuf,0,MB_OK);<BR> break;<BR>   case LINECALLSTATE_IDLE:<BR>    lineDeallocateCall(myhCall);<BR>    break;<BR> case LINECALLSTATE_DISCONNECTED:<BR>  lineClose(myhLine);<BR>  lineShutDown(myhTapi);<BR>  break;<BR> }<BR> }</P><P> ---- 6 被 叫 方 回 调 函 数 的 定 义 </P><P> void far pascal TMyDecFrame::lpfnCallback(DWORD hDevice, DWORD dwMsg,<BR>   DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2,<BR>   DWORD dwParam3)<BR> { int Rec_num=0;</P><P>  switch(dwParam3)<BR>  { case LINECALLPRIVILEGE_OWNER:<BR>    myhCall=(HCALL)hDevice;<BR>    Break;<BR>  }//只有对呼叫具有私有特权的调用者才能应答呼叫,<BR> 在此获得呼叫句柄<BR>  switch(dwParam1)<BR>  { case LINECALLSTATE_CONNECTED:<BR>  DWORD len;<BR>     ClearCommError(myhModem,&Error,&Status);<BR>  Rec_num=ComS.cbInQue;<BR>   ReadFile(myhModem,RecBuf,Rec_num,&len,0);// 清 除 接 收 缓 冲 区<BR>    ReadFile(myhModem,RecBuf,7,&len,0);<BR>   WriteFile(myhModem,"Received",8,&len,0);<BR>    pwin- >MessageBox(RecBuf,0,MB_OK);<BR>  break;<BR>   case LINECALLSTE_OFFERING:<BR>    lineAnswer(myhCall,NULL,0);<BR>    break;// 完 成 自 动 应 答<BR>   case LINECALLSTATE_IDLE:<BR>    lineDeallocateCall(myhCall);<BR>    break;<BR> case LINECALLSTATE_DISCONNECTED:<BR>  lineClose(myhLine);<BR>  lineShutDown(myhTapi);<BR>  break;<BR>   }<BR> }</P><P> 六、 改 进 措 施<BR> ---- 以 上 程 序 中 使 用 的 是 同 步 读 写 方 式, 只 要WriteFile 或 者ReadFile 没 有 完 成 指 定 的I/O 任 务, 它 们 就 不 会 返 回 进 程, 在 许 多 情 况 下, 这 是 令 人 难 以 容 忍 的CPU 时 间 浪 费; 改 进 的 办 法 是 在 每 次 读 之 前 采 用ClearCommError 函 数 确 定 系 统 的 串 行 口 缓 冲 区 中 到 底 有 了 多 少 字 节 的 接 收 数 据, 而 写 方 式 采 用 异 步 方 式, 首 先 应 该 定 义 一 个OVERLAPPED 结 构, 从BC++5.0 中 获 得 的 结 构 定 义 如 下: <BR> typedef struct _OVERLAPPED { // o <BR> DWORD Internal; <BR> DWORD InternalHigh; <BR> DWORD Offset; <BR> DWORD OffsetHigh; <BR> HANDLE hEvent; <BR> } OVERLAPPED; </P><P> ---- 我 们 定 义OVERLAPPED myOVLP; </P><P> ---- 我 们 只 用 到 了 其 中 的hEvent 成 员, 其 他 成 员 均 置0;hEvent 设 置 为CreateEvent(NULL,TRUE,FALSE,NULL) 产 生 的 事 件 句 柄; 然 后 如 下 调 用WriteFile(myhModem,"Received",8,&len,&myOVLP); </P><P> ---- 函 数 将 立 即 返 回, 此 后, 只 要GetOverlappedResult 函 数 返 回TRUE, 写操作就 算 完 成 了。 </P><P>
 

状 态: 离线

公司简介
产品目录

公司名称: 中华工控网
联 系 人: 客服中心
电  话: 0755-26546361
传  真: 0755-26585268
地  址: 深圳市南山区创业路现代城华庭1栋6A
邮  编: 518054
主  页:
 
该厂商相关技术文摘:
智能仪器仪表的发展特点与前景分析
电动机性能虚拟仪器测试系统设计与实现
视频监控护航高铁安全运营
基于PLC,触摸屏及变频器对吹膜机的改造
永宏PLC应用于自助图书借还终端机
基于永宏PLC的GSM通讯原理及其应用
改善汽车生态学、安全性和舒适性,四大测试分析是关键
改善汽车生态学、安全性和舒适性,四大测试分析是关键
数控技术的发展趋势及产业化
数控技术发展战略与发展途径的思考
用Energid 的软件进行机器人的抓取和操作
如何借助RFID技术升级企业信息管理水平
更多文摘...
立即发送询问信息在线联系该技术文摘厂商:
用户名: 密码: 免费注册为中华工控网会员
请留下您的有效联系方式,以方便我们及时与您联络

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 不良信息举报
工控网客服热线:0755-86369299
版权所有 中华工控网 Copyright©2022 Gkong.com, All Rights Reserved