串⼝的读写和缓冲区数据的显⽰
第5章串⼝的读写和缓冲区数据的显⽰
利⽤WIN32API读写串⼝时,既可以同步执⾏,也可以重叠(异步)执⾏。在同步执⾏时,函数直接操作完成后才返回。这意味着同步执⾏时线程会被阻塞,从⽽导致效率降低,在重叠执⾏时,即使操作未完成,调⽤的函数也会⽴即返回。费时的I/O 操作在后台进⾏这样线程就可以做其他⼯作。例如.线程可以在不同的句柄上执⾏I/O操作,甚⾄可以在同⼀句柄上同时进⾏读写操作。“重叠”⼀词含义就在于此。
5.1 读串⼝操作
程序可以使⽤WIN32API ReadFile()函数从串⼝读取数据。
ReadFile()函数声明如下:
BOOL ReadFile(
HANDLE hFile, //指向标识的句柄
LPVOID lpBuffer, //指向⼀个缓冲区
DWORD nNumberOfBytesToRead, //读取的字节数
LPDWORD lpNumberOfBytesRead, //指向调⽤该函数读出的字节数LPOVERLAPPED lpOverlapped //⼀个OVERLAPPED的结构
)
其中主要参数介绍如下:
hFile:指向标识的句柄。对串⼝来说,就是由CreateFile()函数返回的句柄。该句柄需拥有GENERIC—READ的权限。lpBuffer:指向⼀个缓冲区、该缓冲区主要⽤于存放从串⼝设备中读取的数据。
nNumberOfBytesToRead:指定要从串⼝设备读取的字节数
lpNumberOfBytesRead:指向调⽤该函数读出的字节数。ReadFile()在读操作前,⾸先将其设置为0。Windows NT/2000中当lpOverlapped没有设置时,lpNumberOfBytesRead 必需设置。当lpOverlapped设置时,lpNumberOfBytesRead可以不设置。这是可以调⽤GetOverlappedResult()函数获取实际的读取数值。Windows9x中这个参数⼀定要设置.
lpOverlapped :是⼀个0VERLAPPED的结构,如果hFile以
FILE_FLAG_OVERLAPPED⽅式常见, 则需要此结构; 否则, 不需要此结构。
5.2 写串⼝操作
可以使⽤WIN32API函数WriteFile()向串⼝中写数据。
WriteFile()的数声明如下:
BOOL WriteFile(
HANDLE hFile, //指向标识的句柄
LPVOID lpBuffer, //指向⼀个缓冲区
DWORD nNumberOfBytesToWrite,//指定要向串⼝设备写⼊的z字节数LPDWORD lpNumbersOfBytesWritten, //指向调⽤该函数已写⼊的字
节数
LPOVERLAPPEDl lpOverlapped //⼀个OVERLAPPED的结构);
其中主要参数介绍如下:
hFile:指向标识的句柄。对串⼝来说,就是由CreateFile()函数返回的句柄。该句柄需拥有GENERIC—WRITE的权限。pBuffer:指向⼀个缓冲区,该缓冲区主要⽤来存放待写⼊串⼝设备的数据。
nNumberOfBytesToWrite:指定要向串⼝设备写⼊的字节数。
lpNumbersOfBytesWritten:指向调⽤该函数已写⼊出的字节数。
WriteFiIe()在写操作前,⾸先将其设置为0。WindowsNT/2000中当lpOverlapped没有设置时,lpNumbersOfBytesWritten必需设置,当lpOverlapped设置时,lpNumbersOfBytesWritten 可以不设置。这时可以调⽤GetOverlappedResult()函数获取实际读取数值。Windows9x中这个参数⼀定要设置。
lpOverlapped:是⼀个OVERLAPPED的结构,如果hFile以
FILE_FLAS_OVERLAPPED⽅式常见, 则需要此结构; 否则, 不需要此结构。
5.3 异步I/O操作
异步(重叠)I/O操作是指应⽤程序可以在后台读或者写数据.⽽在前台做其他事情。例如,⽤程序可以在开始时对1000个数据进⾏读或写操作,然后返回执⾏其他的操作;在读写完成后,Windows就会
产个⼀个信号,应⽤程序得到这个信号,便可以进⾏其他读写操作。要使⽤OVERLAPPED结构,CreateFile()函数的fdwAttrsAndFlags参数必须设置为
FILE_FLAG_OVERLAPPED标识,读写串⼝函数必须指定OVERLAPPED结构。异步I/O操作在Windows中使⽤⼴泛。OVERLAPPED 结构类型声明如下:
typedef struct_OVERLAPPED{
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
}OVERLAPPED;
其中主要参数如下:
Internal:操作系统保留,指出⼀个和系统相关的状态当GetOverlappedResult()函数返回时,如果将扩展信息设置为ERROR_IO_PENDING,该参数有效。
InternalHigh:操作系统保留,指出发送或接收的数据长度。当GetOverlappedResult()函数返回值不为0时,该参牧有效。Offset和OffsetHigh:指明⽂件传送的开始位置和字节偏移量的⾼位字。当进⾏端⼝操作时,这两个参数被忽略。
hEvent:指定⼀个I/O操作完成后触发的事件(信号)。在调⽤读写函数进⾏I/O操作之前,必需设置该参数。异步I/O操作可以由GetOverlappedResult()函数来获取结果,也可以使⽤Windows信号函数来处理。GetOverlappedResult()函数可声明为:BOOL GetOverlappedResult(
HANDLE hFile,
LPOVERLAPPPED lpoverlapped,
LPDW0RD lPNumberOfBytesTansferred,
BOOL bWait
);
其中主要参数介绍如下:
hFile:标识通信句柄,它应该和开始调⽤重叠结构的ReadFile,WriteFile, WaitCommEvent函数的参数⼀致。lpoverlapped:在启动异步操作时指定的0VERLAPPED结构。
lPNumberOfBytesTansferred:指向⼀个长整型变量,该变量接收有⼀个读或写操作实际传递的字节数。
bWait:指定函数是否等待挂起的异步操作完成。如果该参数设为1,该函数知道I/O 操作完成后才返回。如果该参数被设为0,同时处于披挂起状态,该函数返回为0,且GetLastError()函数返回
ERROR_IO_INCOMPLETE。
如果该函数调⽤成功,则返回值不为零,如果函数调⽤失败,则返回值为零。
Windows也使⽤等待函数来检查事件对象的当前状态或等待Windows 状态信号,在WaitForSingleObject()函数中指定的OVERLAPPED结构中的hEvent即可获取函数返回事件。WaitForSingleObject()函数的的声明如下:DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
其中主要参数如下:
hHandle:指定⼀个司步时间的勾柄,这⾥是指oVERLAPPEd结构中的hEvenl句柄。
dwMilliseconds:以ms为单位指定超时时间。该函数如果调⽤成功,则返回值标识该函数导致该函数返回的事件,否则返回值WAIT_FAILE。成功的返回值可以是以下的三个值之⼀:
WAIT_ABANDONED:等待的对象是互斥对象,并反拥有该对象的线程在终⽌时候没有释放该对象。
WAIT_OBJECT_0:指定的对象处于有信号状态。
WAIT_TIMEOUT:超时事件发⽣后,指定的对象仍处于⽆信号状态。
如果函数调⽤成功,则返回值不为0;如果函数调⽤失败,则返回值为0。如果想获得进⼀步错误信息,可以调⽤GetLastError()函数来获取。
5.4 数据显⽰
为了验证串⼝确实能够接收到和发送数据,要对接收和发送的数据进⾏显⽰,可以为串⾏⼝设置对话框添加⼀个显⽰对话框,在其中设置⼀个编辑框控件,⽤它来显⽰缓冲区中的数据。但由于两对话框间⽆法做到数据共享,所以建⽴⼀个单⽂档程序,由它来对缓冲区中的数据进⾏显⽰。⽂档-视图结构能⽤⽂档管理所有视图的数据,并且能实现多视图间的数据共享。
在⽂档中,设置API⽰例菜单,下设“串⾏⼝设置”,“串⾏⼝连接”,“串⾏⼝断开”菜单项,分别⽤于打开串⾏⼝对话框和指定串⾏⼝连接﹑断开串⾏⼝连接。添加前述的串⾏⼝配置对话框,响应“串⾏⼝设置”菜单操作。
创建单⽂档主程序时,打开Visual Studio6.0,建⽴⼀个名为TTY的MFC应⽤程序。在MFC AppWizard对话框的第⼀步选择Single document;在第六步把CTTYView的基类改为CEditView,使CTTYView继承CeditView的编辑功能,可以利⽤已有的功能函数对数据进⾏显⽰。
数据显⽰窗⼝如图所⽰,他的菜单项内容如表5-1所⽰。
表5-1 添加的菜单项
Table 5-1 The menus added
write的返回值图5-1 数据显⽰对话框
Picture5-1 The Dialog of data display
5.5 本章⼩结
本章介绍如何利⽤重叠读写结构对串⼝进⾏读写访问和如利⽤单⽂档结构对缓冲区中的数据进⾏显⽰。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。