C 扩展windows命名管道以处理客户端信息
处理和处理来自命名管道的数据 我正在尝试实现一个服务提供商来连接硬件设备。 请就我实现一个健壮系统的方法提出一些建议 提到的是提出的要求C 扩展windows命名管道以处理客户端信息,c,windows,driver,named-pipes,C,Windows,Driver,Named Pipes,处理和处理来自命名管道的数据 我正在尝试实现一个服务提供商来连接硬件设备。 请就我实现一个健壮系统的方法提出一些建议 提到的是提出的要求 从其他EXE进程接收数据 处理接收到的Q信息,并在客户端响应通道中发送响应信息 异步将某些故障的信息发送到客户端响应通道 实施上述制度: 已选择2个命名管道(ClntcommandRecv和ClntRespSend)。进程间(IPC)的bcz ClntcommandRecv管道将用作“使用重叠“I/O”的命名管道服务器” ClntRespSend管道将用于发送
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
//#include <strsafe.h>
//#include <glib.h>
#define CONNECTING_STATE 0
#define READING_STATE 1
#define WRITING_STATE 2
#define INSTANCES 4
#define PIPE_TIMEOUT 5000
#define BUFSIZE 4096
typedef struct
{
OVERLAPPED oOverlap;
HANDLE hPipeInst;
TCHAR chRequest[BUFSIZE];
DWORD cbRead;
TCHAR chReply[BUFSIZE];
DWORD cbToWrite;
DWORD dwState;
BOOL fPendingIO;
int processId;
} PIPEINST, *LPPIPEINST;
typedef struct
{
char appName[256];
int processId;
}PIPEHANDSHAKE;
VOID DisconnectAndReconnect(DWORD);
BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);
VOID GetAnswerToRequest(LPPIPEINST);
PIPEINST Pipe[INSTANCES];
HANDLE hEvents[INSTANCES];
HANDLE responsePipeHandle[INSTANCES];
DWORD WINAPI InstanceThread(LPVOID);
HANDLE hPipeHandles[10];
PULONG s;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
LPTSTR lpszResponsePipe = TEXT("\\\\.\\pipe\\mynamedpipe1");
//GHashTable* hash;
int responsePipeConnectionHandler(VOID)
{
BOOL fConnected = FALSE;
DWORD dwThreadId = 0;
HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
int cbBytesRead;
INT threadCount=0;
//hash = g_hash_table_new(g_str_hash, g_str_equal);
char bufferSize[512];
for (;;)
{
_tprintf( TEXT("\nPipe Server: Main thread awaiting client connection on %s\n"), lpszResponsePipe);
hPipe = CreateNamedPipe(
lpszResponsePipe, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
0, // client time-out
NULL); // default security attribute
if (hPipe == INVALID_HANDLE_VALUE)
{
_tprintf(TEXT("CreateNamedPipe failed, GLE=%d.\n"), GetLastError());
return -1;
}
// Wait for the client to connect; if it succeeds,
// the function returns a nonzero value. If the function
// returns zero, GetLastError returns ERROR_PIPE_CONNECTED.
fConnected = ConnectNamedPipe(hPipe, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if(fConnected){
PIPEHANDSHAKE processData;
fConnected = ReadFile(
hPipe, // handle to pipe
bufferSize, // buffer to receive data
sizeof(PIPEHANDSHAKE), // size of buffer
&cbBytesRead, // number of bytes read
NULL); // not overlapped I/O
memset(&processData,0,sizeof(PIPEHANDSHAKE));
memcpy(&processData,&bufferSize,sizeof(PIPEHANDSHAKE));
printf("APP Process id: %d , app name: %s",processData.processId,processData.appName);
}
/* if (fConnected)
{
printf("Client connected, creating a processing thread.\n");
// Create a thread for this client.
hThread = CreateThread(
NULL, // no security attribute
0, // default stack size
InstanceThread, // thread proc
(LPVOID) hPipe, // thread parameter
0, // not suspended
&dwThreadId); // returns thread ID
if (hThread == NULL)
{
_tprintf(TEXT("CreateThread failed, GLE=%d.\n"), GetLastError());
return -1;
}
else CloseHandle(hThread);
}
else
// The client could not connect, so close the pipe.
CloseHandle(hPipe);*/
}
return 0;
}
int _tmain(VOID)
{
DWORD i, dwWait, cbRet, dwErr,hThread;
BOOL fSuccess;
int dwThreadId;
// The initial loop creates several instances of a named pipe
// along with an event object for each instance. An
// overlapped ConnectNamedPipe operation is started for
// each instance.
// Create response pipe thread
hThread = CreateThread(
NULL, // no security attribute
0, // default stack size
responsePipeConnectionHandler, // thread proc
NULL, // thread parameter
0, // not suspended
&dwThreadId); // returns thread ID
if (hThread == NULL)
{
printf("Response server creation failed with %d.\n", GetLastError());
return 0;
}
for (i = 0; i < INSTANCES; i++)
{
// Create an event object for this instance.
hEvents[i] = CreateEvent(
NULL, // default security attribute
TRUE, // manual-reset event
TRUE, // initial state = signaled
NULL); // unnamed event object
if (hEvents[i] == NULL)
{
printf("CreateEvent failed with %d.\n", GetLastError());
return 0;
}
Pipe[i].oOverlap.hEvent = hEvents[i];
Pipe[i].hPipeInst = CreateNamedPipe(
lpszPipename, // pipe name
PIPE_ACCESS_DUPLEX | // read/write access
FILE_FLAG_OVERLAPPED, // overlapped mode
PIPE_TYPE_MESSAGE | // message-type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
INSTANCES, // number of instances
BUFSIZE*sizeof(TCHAR), // output buffer size
BUFSIZE*sizeof(TCHAR), // input buffer size
PIPE_TIMEOUT, // client time-out
NULL); // default security attributes
if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipe failed with %d.\n", GetLastError());
return 0;
}
// Call the subroutine to connect to the new client
Pipe[i].fPendingIO = ConnectToNewClient(
Pipe[i].hPipeInst,
&Pipe[i].oOverlap);
Pipe[i].dwState = Pipe[i].fPendingIO ?
CONNECTING_STATE : // still connecting
READING_STATE; // ready to read
}
while (1)
{
dwWait = WaitForMultipleObjects(
INSTANCES, // number of event objects
hEvents, // array of event objects
FALSE, // does not wait for all
INFINITE); // waits indefinitely
// dwWait shows which pipe completed the operation.
i = dwWait - WAIT_OBJECT_0; // determines which pipe
if (i < 0 || i > (INSTANCES - 1))
{
printf("Index out of range.\n");
return 0;
}
// Get the result if the operation was pending.
if (Pipe[i].fPendingIO)
{
fSuccess = GetOverlappedResult(
Pipe[i].hPipeInst, // handle to pipe
&Pipe[i].oOverlap, // OVERLAPPED structure
&cbRet, // bytes transferred
FALSE); // do not wait
switch (Pipe[i].dwState)
{
// Pending connect operation
case CONNECTING_STATE:
if (! fSuccess)
{
printf("Error %d.\n", GetLastError());
return 0;
}
Pipe[i].dwState = READING_STATE;
break;
// Pending read operation
case READING_STATE:
if (! fSuccess || cbRet == 0)
{
DisconnectAndReconnect(i);
continue;
}
Pipe[i].cbRead = cbRet;
Pipe[i].dwState = WRITING_STATE;
break;
// Pending write operation
case WRITING_STATE:
if (! fSuccess || cbRet != Pipe[i].cbToWrite)
{
DisconnectAndReconnect(i);
continue;
}
Pipe[i].dwState = READING_STATE;
break;
default:
{
printf("Invalid pipe state.\n");
return 0;
}
}
}
// The pipe state determines which operation to do next.
switch (Pipe[i].dwState)
{
case READING_STATE:
fSuccess = ReadFile(
Pipe[i].hPipeInst,
Pipe[i].chRequest,
BUFSIZE*sizeof(TCHAR),
&Pipe[i].cbRead,
&Pipe[i].oOverlap);
if (fSuccess && Pipe[i].cbRead != 0)
{
Pipe[i].fPendingIO = FALSE;
Pipe[i].dwState = WRITING_STATE;
continue;
}
dwErr = GetLastError();
if (! fSuccess && (dwErr == ERROR_IO_PENDING))
{
Pipe[i].fPendingIO = TRUE;
continue;
}
DisconnectAndReconnect(i);
break;
case WRITING_STATE:
GetAnswerToRequest(&Pipe[i]);
fSuccess = WriteFile(
Pipe[i].hPipeInst,
Pipe[i].chReply,
Pipe[i].cbToWrite,
&cbRet,
&Pipe[i].oOverlap);
if (fSuccess && cbRet == Pipe[i].cbToWrite)
{
Pipe[i].fPendingIO = FALSE;
Pipe[i].dwState = READING_STATE;
continue;
}
dwErr = GetLastError();
if (! fSuccess && (dwErr == ERROR_IO_PENDING))
{
Pipe[i].fPendingIO = TRUE;
continue;
}
DisconnectAndReconnect(i);
break;
default:
{
printf("Invalid pipe state.\n");
return 0;
}
}
}
return 0;
}
VOID DisconnectAndReconnect(DWORD i)
{
if (! DisconnectNamedPipe(Pipe[i].hPipeInst) )
{
printf("DisconnectNamedPipe failed with %d.\n", GetLastError());
}
Pipe[i].fPendingIO = ConnectToNewClient(
Pipe[i].hPipeInst,
&Pipe[i].oOverlap);
Pipe[i].dwState = Pipe[i].fPendingIO ?
CONNECTING_STATE : // still connecting
READING_STATE; // ready to read
}
BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo)
{
BOOL fConnected, fPendingIO = FALSE;
fConnected = ConnectNamedPipe(hPipe, lpo);
if (fConnected)
{
printf("ConnectNamedPipe failed with %d.\n", GetLastError());
return 0;
}
switch (GetLastError())
{
// The overlapped connection in progress.
case ERROR_IO_PENDING:
fPendingIO = TRUE;
break;
case ERROR_PIPE_CONNECTED:
if (SetEvent(lpo->hEvent))
break;
default:
{
printf("ConnectNamedPipe failed with %d.\n", GetLastError());
return 0;
}
}
return fPendingIO;
}
int rxProccesIdMsg(HANDLE pipe)
{
PIPEHANDSHAKE pipeInfo;
CHAR bufferSize[512] = {'\0'};
INT cbBytesRead;
BOOL fSuccess;
PIPEHANDSHAKE processData;
fSuccess = ReadFile(
pipe, // handle to pipe
bufferSize, // buffer to receive data
sizeof(PIPEHANDSHAKE), // size of buffer
&cbBytesRead, // number of bytes read
NULL); // not overlapped I/O
memset(&processData,0,sizeof(PIPEHANDSHAKE));
memcpy(&processData,&bufferSize,sizeof(PIPEHANDSHAKE));
if ( (!fSuccess))
{
printf("Client: READ Server Pipe Failed(%d)\n",GetLastError());
CloseHandle(pipe);
return -1;
}
else
{
printf("Client: READ Server Pipe Success(%d)\n",GetLastError());
printf("APP Process id: %d , app name: %s",processData.processId,processData.appName);
//Sleep(3*100);
}
return processData.processId;
}
VOID GetAnswerToRequest(LPPIPEINST pipe)
{
_tprintf( TEXT("[%d] %s\n"), pipe->hPipeInst, pipe->chRequest);
// StringCchCopy( pipe->chReply, BUFSIZE, TEXT("Default answer from server") );
strncpy(pipe->chReply, "Default answer from server",BUFSIZE);
pipe->cbToWrite = (lstrlen(pipe->chReply)+1)*sizeof(TCHAR);
}
#包括
#包括
#包括
//#包括
//#包括
#定义连接状态0
#定义读取状态1
#定义写入状态2
#定义实例4
#定义管道超时5000
#定义BUFSIZE 4096
类型定义结构
{
重叠的卵缘;
处理水管;
TCHAR chRequest[BUFSIZE];
德沃德·克莱德;
TCHAR chReply[BUFSIZE];
德沃德·克托维特;
德沃德州;
布尔·芬丁吉奥;
int进程ID;
}管道仪表,*LPPIPEINST;
类型定义结构
{
字符appName[256];
int进程ID;
}握手;
无效断开和连接(DWORD);
BOOL ConnectToNewClient(手柄,重叠);
无效获取应答请求(LPPIPEINST);
PIPEINST管道[实例];
处理事件[实例];
HANDLE responsepehandle[实例];
DWORD WINAPI实例线程(LPVOID);
手柄[10];
普隆s;
LPTSTR lpszPipename=TEXT(“\\\.\\pipe\\mynamedpipe”);
LPTSTR lpszresponsepie=TEXT(“\\\.\\pipe\\mynamedpipe1”);
//GHashTable*散列;
int ResponseEpieConnectionHandler(无效)
{
BOOL fConnected=FALSE;
DWORD dwThreadId=0;
HANDLE hPipe=INVALID\u HANDLE\u值,hThread=NULL;
int-cbBytesRead;
INT threadCount=0;
//hash=g_hash_table_new(g_str_hash,g_str_equal);
字符缓冲大小[512];
对于(;;)
{
_tprintf(文本(“\n管道服务器:主线程在%s上等待客户端连接,\n”)、lpszresponsepe;
hPipe=CreateNamedPipe(
lpszResponsePipe,//管道名称
管道\u访问\u双工,//读/写访问
PIPE_TYPE_MESSAGE |//消息类型PIPE
管道读取模式消息读取模式
管道\u等待,//阻塞模式
管道\无限\实例,//最大实例数
BUFSIZE,//输出缓冲区大小
BUFSIZE,//输入缓冲区大小
0,//客户端超时
NULL);//默认安全属性
if(hPipe==无效的句柄值)
{
_tprintf(TEXT(“CreateNamedPipe失败,GLE=%d.\n”)、GetLastError();
返回-1;
}
//等待客户端连接;如果成功,
//函数返回一个非零值。如果
//返回零,GetLastError返回错误\u管道\u连接。
fConnected=ConnectNamedPipe(hPipe,NULL)?
TRUE:(GetLastError()==错误\u管道\u已连接);
如果(fConnected){
管道握手处理数据;
fConnected=ReadFile(
hPipe,//句柄到管道
bufferSize,//用于接收数据的缓冲区
sizeof(PIPEHANDSHAKE),//缓冲区大小
&cbBytesRead,//读取的字节数
NULL);//不重叠的I/O
memset(&processData,0,sizeof(PIPEHANDSHAKE));
memcpy(&processData,&bufferSize,sizeof(PIPEHANDSHAKE));
printf(“应用程序进程id:%d,应用程序名称:%s”,processData.processId,processData.appName);
}
/*如果(fConnected)
{
printf(“客户端已连接,正在创建处理线程。\n”);
//为此客户端创建一个线程。
hThread=CreateThread(
NULL,//没有安全属性
0,//默认堆栈大小
InstanceThread,//线程进程
(LPVOID)hPipe,//线程参数
0,//未挂起
&dwThreadId);//返回线程ID
if(hThread==NULL)
{
_tprintf(文本(“CreateThread失败,GLE=%d.\n”)、GetLastError();
返回-1;
}
else CloseHandle(hThread);
}
其他的
//客户端无法连接,因此请关闭管道。
闭柄(hPipe)*/
}
返回0;
}
内部(无效)
{
dwordi、dwWait、cbRet、dwErr、hThread;
成功;
int-dwThreadId;
//初始循环将创建命名管道的多个实例
//以及每个实例的事件对象
//重叠连接命名管道opera