多线程,重叠I/O,异步读写 命名通道服务器源码
来源:互联网 发布:智取威虎山 老八 知乎 编辑:程序博客网 时间:2024/05/16 16:08
/*
* 文件名称:NamedPipeServer.cpp
*
* 文件作用:测试建立多线程复杂命名管道服务器
*
* 完成日期:2007.04.03
*/
#include <windows.h>
#include <stdio.h>
#define NUM_PIPES 5
#define BUFFER_SIZE 256
void main( void )
{
HANDLE PipeHandles[NUM_PIPES];
DWORD BytesTransferred;
CHAR Buffer[NUM_PIPES][BUFFER_SIZE];
INT i;
OVERLAPPED Ovlap[NUM_PIPES];
HANDLE Event[NUM_PIPES];
// 对每一个通道句柄实例来说,当它进行在读写操作时,代码必须维持通道的当前状态
// 这个可以用DataRead这个变量数组来实现.当我们确定了管道的当前状态,代码能够
// 确定下一个I/O操作是什么
BOOL DataRead[ NUM_PIPES ];
DWORD Ret;
DWORD Pipe;
for( i = 0; i < NUM_PIPES; i++ )
{
// 为每个命名管道实例创建一个线程,并调用其回调函数
if ((PipeHandles[i] = CreateNamedPipe("////.//PIPE//jim",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, NUM_PIPES,
0, 0, 1000, NULL)) == INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipe for pipe %d failed "
"with error %d/n", i, GetLastError());
return;
}
// 为每个命名通道创建一个事件句柄
if ((Event[i] = CreateEvent(NULL, TRUE, FALSE, NULL))
== NULL)
{
printf("CreateEvent for pipe %d failed with error %d/n",
i, GetLastError());
continue;
}
// 当确定命名通道在进行读写工作时候,为其维持一个状态
DataRead[i] = FALSE;
ZeroMemory(&Ovlap[i], sizeof(OVERLAPPED));
Ovlap[i].hEvent = Event[i];
// 监听客户端,使用异步操作,不需要僵直等待
if ( ConnectNamedPipe(PipeHandles[i], &Ovlap[i]) == 0)
{
if ( GetLastError() != ERROR_IO_PENDING )
{
printf("ConnectNamedPipe for pipe %d failed with",
" error %d/n", i, GetLastError());
CloseHandle(PipeHandles[i]);
return;
}
}
}
printf("Server is now running/n");
// 持续处理客户端信息
while( 1 )
{
if (( Ret = WaitForMultipleObjects(NUM_PIPES, Event,
FALSE, INFINITE)) == WAIT_FAILED )
{
printf("WaitForMultipleObjects failed with error %d/n",
GetLastError());
return;
}
Pipe = Ret - WAIT_OBJECT_0;
ResetEvent(Event[Pipe]);
// 检查重叠异步结果,如果失败,则和新的客户端重建链接
// 不然,和客户端处理读写过程
if ( GetOverlappedResult(PipeHandles[Pipe], &Ovlap[Pipe],
&BytesTransferred, TRUE) == 0 )
{
printf("GetOverlapped result failed %d start over/n",
GetLastError());
if (DisconnectNamedPipe(PipeHandles[Pipe]) == 0)
{
printf("DisconnectNamedPipe failed with error %d/n",
GetLastError());
return;
}
if (ConnectNamedPipe(PipeHandles[Pipe],
&Ovlap[Pipe]) == 0)
{
if (GetLastError() != ERROR_IO_PENDING)
{
// 命名通道出现严重错误,永久性关闭句柄
printf("ConnectNamedPipe for pipe %d failed with"
"error %d/n", i, GetLastError());
CloseHandle(PipeHandles[Pipe]);
}
}
DataRead[Pipe] = FALSE;
}
else
{
// 检查通道状态,如果DataRead是FALSE,则对通道输入数据进行读操作
// 若DataRead状态是TRUE,则准备对客户端进行信息反馈
if (DataRead[Pipe] == FALSE)
{
// 准备从客户端进行数据的读取
ZeroMemory(&Ovlap[Pipe], sizeof(OVERLAPPED));
Ovlap[Pipe].hEvent = Event[Pipe];
if (ReadFile(PipeHandles[Pipe], Buffer[Pipe],
BUFFER_SIZE, NULL, &Ovlap[Pipe]) == 0)
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("ReadFile failed with error %d/n",
GetLastError());
}
}
DataRead[Pipe] = TRUE;
}
else
{
// 对客户端进行反馈信息的写入操作
printf("Received %d bytes, echo bytes back/n",
BytesTransferred);
ZeroMemory(&Ovlap[Pipe], sizeof(OVERLAPPED));
Ovlap[Pipe].hEvent = Event[Pipe];
if (WriteFile(PipeHandles[Pipe], Buffer[Pipe],
BytesTransferred, NULL, &Ovlap[Pipe]) == 0)
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("WriteFile failed with error %d/n",
GetLastError());
}
}
DataRead[Pipe] = FALSE;
}
}
}
}
- 多线程,重叠I/O,异步读写 命名通道服务器源码
- 多线程,重叠I/O,异步读写 命名通道服务器源码
- [使用重叠IO的命名管道服务器示例]Named Pipe Server Using Overlapped I/O
- I/O重叠结构服务器代码
- WinSock 异步I/O模型[4]---重叠 I/O - Overlapped I/O
- Windows 命名管道 + 异步I/O模型
- Windows 命名管道 + 异步I/O模型
- 异步套接字编程之重叠I/O模型
- 异步套接字编程之重叠I/O模型
- Java 7之异步I/O第5篇 - 异步I/O操作之通道
- 多线程同步I/O和单线程异步I/O
- 重叠I/O模型
- 重叠I/O模型
- 重叠I/O模型
- 什么是重叠I/O
- 重叠I/O模型
- 慎用重叠I/O
- 什么是重叠I/O
- ubuntu下如何处理rar文档
- C#数据库入门-012:数据读取器
- xfire_namespaceuri canot be null
- Linux文件系统(三)—— 文件系统常用工具介绍
- C#数据库入门-013:数据集和数据适配器
- 多线程,重叠I/O,异步读写 命名通道服务器源码
- 读NORFLASH ID初体验
- 一些VC生成动态链接库的问题记载(不断更新中)
- ORACLE 性能调试 总结中ing
- windows平台.lnk文件感染技术研究
- 祝福所有朋友
- 查询数据库更改
- http文件头详解
- MARK关于临界区