⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap12_3.htm

📁 MFC开发基础教程
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<html>

<head>
<title>12.3 串行通信与重叠I/O</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
</head>

<body link="#3973DE" alink="#3973DE">
<font SIZE="5"><b><div align="center"><center>

<table border="0" width="615" cellspacing="0" cellpadding="0">
  <tr>
    </b><td><div align="center"><center><table border="0" width="615" cellpadding="0" cellspacing="0" height="20">
      <tr>
        <td width="377" bgcolor="#15397D" height="20"></td>
        <td width="238" bgcolor="#000000" height="20"><p align="right"></font><span style="text-decoration: none"><a href="../../index.htm"><font color="#FFFFFF">电脑报Visual 
        C++网络教程</font></a></span></td>
      </tr>
    </table>
    </center></div><font FACE="Times New Roman" SIZE="3"><b><p ALIGN="CENTER"></b></font><font color="#3973DE" FACE="Times New Roman" size="4">12.3 </font><font color="#3973DE" size="4">串行通信与重叠</font><font color="#3973DE" FACE="Times New Roman" size="4">I/O</font><font FACE="Times New Roman" size="4"></p>
    </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">Win 32</font><font SIZE="3">系统为串行通信提供了全新的服务。传统的</font><font FACE="Times New Roman" SIZE="3">OpenComm</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">ReadComm</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">WriteComm</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">CloseComm</font><font SIZE="3">等函数已经过时,</font><font FACE="Times New Roman" SIZE="3">WM_COMMNOTIFY</font><font SIZE="3">消息也消失了。取而代之的是文件</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">函数提供的打开和关闭通信资源句柄及读写操作的基本接口。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">新的文件</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">函数</font><font FACE="Times New Roman" SIZE="3">(CreateFile</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">ReadFile</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">WriteFile</font><font SIZE="3">等</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">支持重叠式输入输出,这使得线程可以从费时的</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">操作中解放出来,从而极大地提高了程序的运行效率。</font><font FACE="Times New Roman" SIZE="3"></p>
    <b><p ALIGN="JUSTIFY"></b></font><font color="#3973DE" FACE="Times New Roman" SIZE="3">12.3.1 
    </font><font SIZE="3" color="#3973DE">串行口的打开和关闭</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">Win 32</font><font SIZE="3">系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用</font><font FACE="Times New Roman" SIZE="3">API</font><font SIZE="3">函数</font><font FACE="Times New Roman" SIZE="3">CreateFile</font><font SIZE="3">来打开或创建的。该函数的声明为:</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">HANDLE CreateFile(</p>
    <p ALIGN="JUSTIFY">LPCTSTR lpFileName, // </font><font SIZE="3">文件名 </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">DWORD dwDesiredAccess, // </font><font SIZE="3">访问模式 </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">DWORD dwShareMode, // </font><font SIZE="3">共享模式 </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">LPSECURITY_ATTRIBUTES lpSecurityAttributes, // </font><font SIZE="3">通常为</font><font FACE="Times New Roman" SIZE="3">NULL</p>
    <p ALIGN="JUSTIFY">DWORD dwCreationDistribution, // </font><font SIZE="3">创建方式 </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">DWORD dwFlagsAndAttributes, // </font><font SIZE="3">文件属性和标志</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">HANDLE hTemplateFile // </font><font SIZE="3">临时文件的句柄,通常为</font><font FACE="Times New Roman" SIZE="3">NULL </p>
    <blockquote>
      <p ALIGN="JUSTIFY">);</p>
    </blockquote>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回</font><font FACE="Times New Roman" SIZE="3">INVALID_HANDLE_VALUE</font><font SIZE="3">。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">如果想要用重叠</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">方式(参见</font><font FACE="Times New Roman" SIZE="3">12.3.3</font><font SIZE="3">)打开</font><font FACE="Times New Roman" SIZE="3">COM2</font><font SIZE="3">口,则一般应象清单</font><font FACE="Times New Roman" SIZE="3">12.4</font><font SIZE="3">那样调用</font><font FACE="Times New Roman" SIZE="3">CreateFile</font><font SIZE="3">函数。注意在打开一个通信端口时,应该以独占方式打开,另外要指定</font><font FACE="Times New Roman" SIZE="3">GENERIC_READ</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">GENERIC_WRITE</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">OPEN_EXISTING</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">FILE_ATTRIBUTE_NORMAL</font><font SIZE="3">等属性。如果要打开重叠</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">,则应该指定 </font><font FACE="Times New Roman" SIZE="3">FILE_FLAG_OVERLAPPED</font><font SIZE="3">属性。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><b><font SIZE="3"> </p>
    <p ALIGN="JUSTIFY">清单</font><font FACE="Times New Roman" SIZE="3">12.4</b></p>
    <p ALIGN="JUSTIFY">HANDLE hCom;</p>
    <p ALIGN="JUSTIFY">DWORD dwError;</p>
    <p ALIGN="JUSTIFY">hCom=CreateFile(</font><font SIZE="3">“</font><font FACE="Times New Roman" SIZE="3">COM2</font><font SIZE="3">”</font><font FACE="Times New Roman" SIZE="3">, // </font><font SIZE="3">文件名</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">GENERIC_READ | GENERIC_WRITE, // </font><font SIZE="3">允许读和写 </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">0, // </font><font SIZE="3">独占方式</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">NULL, </p>
    <p ALIGN="JUSTIFY">OPEN_EXISTING, //</font><font SIZE="3">打开而不是创建</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // </font><font SIZE="3">重叠方式</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">NULL</p>
    <p ALIGN="JUSTIFY">);</p>
    <p ALIGN="JUSTIFY">if(hCom = = INVALID_HANDLE_VALUE)</p>
    <p ALIGN="JUSTIFY">{</p>
    <p ALIGN="JUSTIFY">dwError=GetLastError( );</p>
    <p ALIGN="JUSTIFY"><b>. . .</b> // </font><font SIZE="3">处理错误</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">}</p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">当不再使用文件句柄时,应该调用</font><font FACE="Times New Roman" SIZE="3">CloseHandle</font><font SIZE="3">函数关闭之。</font><font FACE="Times New Roman" SIZE="3"></p>
    <b><p ALIGN="JUSTIFY"></b></font><font color="#3973DE" FACE="Times New Roman" SIZE="3">12.3.2 
    </font><font SIZE="3" color="#3973DE">串行口的初始化</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。这需要通过一个</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">结构来进行。</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置置串行口的属性时,都要用</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">结构来作为缓冲区。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">调用</font><font FACE="Times New Roman" SIZE="3">GetCommState</font><font SIZE="3">函数可以获得串口的配置,该函数把当前配置填充到一个</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">结构中。一般在用</font><font FACE="Times New Roman" SIZE="3">CreateFile</font><font SIZE="3">打开串行口后,可以调用</font><font FACE="Times New Roman" SIZE="3">GetCommState</font><font SIZE="3">函数来获取串行口的初始配置。要修改串行口的配置,应该先修改</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">结构,然后再调用</font><font FACE="Times New Roman" SIZE="3">SetCommState</font><font SIZE="3">函数用指定的</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">结构来设置串行口。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">除了在</font><font FACE="Times New Roman" SIZE="3">DCB</font><font SIZE="3">中的设置外,程序一般还需要设置</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">缓冲区的大小和超时。</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">用</font><font FACE="Times New Roman" SIZE="3">I/O</font><font SIZE="3">缓冲区来暂存串行口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。调用</font><font FACE="Times New Roman" SIZE="3">SetupComm</font><font SIZE="3">函数可以设置串行口的输入和输出缓冲区的大小。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">在用</font><font FACE="Times New Roman" SIZE="3">ReadFile</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">WriteFile</font><font SIZE="3">读写串行口时,需要考虑超时问题。如果在指定的时间内没有读出或写入指定数量的字符,那么</font><font FACE="Times New Roman" SIZE="3">ReadFile</font><font SIZE="3">或</font><font FACE="Times New Roman" SIZE="3">WriteFile</font><font SIZE="3">的操作就会结束。要查询当前的超时设置应调用</font><font FACE="Times New Roman" SIZE="3">GetCommTimeouts</font><font SIZE="3">函数,该函数会填充一个</font><font FACE="Times New Roman" SIZE="3">COMMTIMEOUTS</font><font SIZE="3">结构。调用</font><font FACE="Times New Roman" SIZE="3">SetCommTimeouts</font><font SIZE="3">可以用某一个</font><font FACE="Times New Roman" SIZE="3">COMMTIMEOUTS</font><font SIZE="3">结构的内容来设置超时。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用</font><font FACE="Times New Roman" SIZE="3">COMMTIMEOUTS</font><font SIZE="3">结构可以规定读</font><font FACE="Times New Roman" SIZE="3">/</font><font SIZE="3">写操作的超时,该结构的定义为:</p>
    <blockquote>
      </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">typedef struct 
      _COMMTIMEOUTS { </p>
      <p ALIGN="JUSTIFY">DWORD ReadIntervalTimeout; // </font><font SIZE="3">读间隔超时</p>
      </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">DWORD 
      ReadTotalTimeoutMultiplier; // </font><font SIZE="3">读时间系数</p>
      </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">DWORD 
      ReadTotalTimeoutConstant; // </font><font SIZE="3">读时间常量</p>
      </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">DWORD 
      WriteTotalTimeoutMultiplier; // </font><font SIZE="3">写时间系数</p>
      </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">DWORD 
      WriteTotalTimeoutConstant; // </font><font SIZE="3">写时间常量</p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -