ReadFile , , PeekNamedPipe. ( ), , , .
BOOL PeekNamedPipe(HANDLE hPipe, LPVOID lpBuffer, DWORD cbBuffer, LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage)
PeekNamedPipe , , .
, , *lpcbAvail; , 0. lpBuffer lpcbRead NULL. lpBuffer cbBuffer, *lpcbMessage , , , , . , , 0.
, PeekNamedPipe , , ReadFile.
UNIX FIFO , , . Windows :
FIFO .
FIFO .
FIFO , - . , .
, , FIFO, . FIFO .
UNIX mkfifo CreateNamedFile.
, . , .
: -
- , . , . :
|
|
.
, .
, . , (thread pool), , . , .
, . . , , .
11.2 , 11.3 . , 7.1 11.2. . , . , Web- ClntSrvr.h, , .
11.2 LocateServer, . LocateServer (mailslot), 11.5.
, DWORD32; , , Win64, , Windows.
11.2. clientNP: ,
/* 11. - . .
clientNP , . */
/* ( ); . */
/* ( */
/* ) .*/
#include "EvryThng.h"
#include "ClntSrvr.h" /* . */
int _tmain(int argc, LPTSTR argv[]) {
HANDLE hNamedPipe = INVALID_HANDLE_VALUE;
TCHAR PromptMsg[] = _T("\n : ");
TCHAR QuitMsg[] = _T("$Quit");
TCHAR ServerPipeName[MAX_PATH];
REQUEST Request; /* . ClntSrvr.h. */
RESPONSE Response; /* . ClntSrvr.h. */
DWORD nRead, nWrite, NpMode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
LocateServer(ServerPipeName);
/* " " . */
while (INVALID_HANDLE_VALUE == hNamedPipe) {
WaitNamedPipe(ServerPipeName, NMPWAIT_WAIT_FOREVER);
hNamedPipe = CreateFile(ServerPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
/* ; .*/
|
|
SetNamedPipeHandleState(hNamedPipe, &NpMode, NULL, NULL);
/* . "$quit." */
while (ConsolePrompt(PromptMsg, Request.Record, MAX_RQRS_LEN, TRUE) && (_tcscmp(Request.Record, QuitMsg)!= 0)) {
WriteFile(hNamedPipe, &Request, RQ_SIZE, &nWrite, NULL);
/* .
Response.Status = 0 " ." */
while (ReadFile(hNamedPipe, &Response, RS_SIZE, &nRead, NULL) && (Response.Status == 0)) _tprintf(_T("%s"), Response.Record);
}
_tprintf(_T(" . ."));
CloseHandle(hNamedPipe);
return 0;
}
11.3 , , , 11.2. , " " ("server broadcast thread") (. 11.4), , , . 11.2 LocateServer, 11.5, , . .
11.4, ( Web-) , . 15, , .
11.3. serverNP:
/* 11. ServerNP. */
/* . . */
#include "EvryThng.h"
#include "ClntSrvr.h" /* . */
typedef struct { /* . */
HANDLE hNamedPipe; /* . */
DWORD ThreadNo;
TCHAR TmpFileName[MAX_PATH]; /* . */
} THREAD_ARG;
typedef THREAD_ARG *LPTHREAD_ARG;
volatile static BOOL ShutDown = FALSE;
static DWORD WINAPI Server(LPTHREAD_ARG);
static DWORD WINAPI Connect(LPTHREAD_ARG);
static DWORD WINAPI ServerBroadcast(LPLONG);
static BOOL WINAPI Handler(DWORD);
static TCHAR ShutRqst[] = _T("$ShutDownServer");
_tmain(int argc, LPTSTR argv[]) {
/* MAX_CLIENTS ClntSrvr.h. */
HANDLE hNp, hMonitor, hSrvrThread[MAXCLIENTS];
DWORD iNp, MonitorId, ThreadId;
LPSECURITY_ATTRIBUTES pNPSA = NULL;
THREAD_ARG ThArgs[MAXCLIENTS];
/* , . */
SetConsoleCtrlHandler(Handler, TRUE);
/* . */
hMonitor = (HANDLE)_beginthreadex(NULL, 0, ServerBroadcast, NULL, 0, &MonitorId);
/* . */
for (iNp = 0; iNp < MAX_CLIENTS; iNp++) {
hNp = CreateNamedPipe(SERVER_PIPE, PIPE_ACCESS_DUPLEX, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, MAXCLIENTS, 0, 0, INFINITE, pNPSA);
ThArgs[iNp].hNamedPipe = hNp;
ThArgs[iNp].ThreadNo = iNp;
GetTempFileName(_T("."), _T("CLP"), 0, ThArgs[iNp].TmpFileName);
hSrvrThread[iNp] = (HANDLE)_beginthreadex(NULL, 0, Server, &ThArgs[iNp], 0, &ThreadId);
}
/* . */
WaitForMultipleObjects(MAXCLIENTS, hSrvrThread, TRUE, INFINITE);
WaitForSingleObject(hMonitor, INFINITE);
CloseHandle(hMonitor);
for (iNp = 0; iNp < MAXCLIENTS; iNp++) {
/* . */
|
|
CloseHandle(hSrvrThread[iNp]);
DeleteFile(ThArgs[iNp].TmpFileName);
}
_tprintf(_T(" .\n"));
return 0;
}
static DWORD WINAPI Server(LPTHREAD_ARG pThArg)
/* ; . */
{
HANDLE hNamedPipe, hTmpFile = INVALID_HANDLE_VALUE, hConTh, hClient;
DWORD nXfer, ConThId, ConThStatus;
STARTUPINFO StartInfoCh;
SECURITY_ATTRIBUTES TempSA = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
PROCESS_INFORMATION ProcInfo;
FILE *fp;
REQUEST Request;
RESPONSE Response;
GetStartupInfo(&StartInfoCh);
hNamedPipe = pThArg->hNamedPipe;
hTmpFile = CreateFile(pThArg->TmpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &TempSA, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
while (!ShutDown) { /* . */
/* ; . */
hConTh = (HANDLE)_beginthreadex(NULL, 0, Connect, pThArg, 0, &ConThId);
/* .*/
while (!ShutDown && WaitForSingleObject(hConTh, CS_TIMEOUT) == WAIT_TIMEOUT) { /* . */ };
CloseHandle(hConTh);
if (ShutDown) continue; /* .*/
/* . */
while (!ShutDown && ReadFile(hNamedPipe, &Request, RQ_SIZE, &nXfer, NULL)) {
/* . */
ShutDown = ShutDown || (_tcscmp(Request.Record, ShutRqst) == 0);
if (ShutDown) continue; /* . */
/* . */
StartInfoCh.hStdOutput = hTmpFile;
StartInfoCh.hStdError = hTmpFile;
StartInfoCh.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
StartInfoCh.dwFlags = STARTF_USESTDHANDLES;
CreateProcess(NULL, Request.Record, NULL, NULL, TRUE, /* . */
0, NULL, NULL, &StartInfoCh, &ProcInfo);
/* . */
CloseHandle(ProcInfo.hThread);
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
CloseHandle(ProcInfo.hProcess);
/* . . */
fp = _tfopen(pThArg->TmpFileName, _T("r"));
Response.Status = 0;
while(_fgetts(Response.Record, MAX_RQRS_LEN, fp)!= NULL) WriteFile(hNamedPipe, &Response, RS_SIZE, &nXfer, NULL);
FlushFileBuffers(hNamedPipe);
fclose(fp);
/* . */
SetFilePointer(hTmpFile, 0, NULL, FILE_BEGIN);
SetEndOfFile(hTmpFile);
/* . */
Response.Status = 1;
strcpy(Response.Record, "");
WriteFile(hNamedPipe, &Response, RS_SIZE, &nXfer, NULL);
}
/* . . */
/* , .*/
GetExitCodeThread(hConTh, &ConThStatus);
if (ConThStatus == STILL_ACTIVE) {
hClient = CreateFile(SERVER_PIPE, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN EXISTING, FILE ATTRIBUTE NORMAL, NULL);
if (hClient!= INVALID_HANDLE_VALUE) CloseHandle (hClient);
WaitForSingleObject (hConTh, INFINITE);
}
/* . */
FlushFileBuffers(hNamedPipe);
DisconnectNamedPipe(hNamedPipe);
}
/* . ; . */
if (hTmpFile!= INVALID_HANDLE_VALUE) CloseHandle(hTmpFile);
DeleteFile(pThArg->TmpFileName);
_tprintf(_T(" %d\n"), pThArg->ThreadNo);
_endthreadex(0);
}
static DWORD WINAPI Connect(LPTHREAD_ARG pThArg) {
/* ShutDown. */
ConnectNamedPipe(pThArg->hNamedPipe, NULL);
_endthreadex(0);
return 0;
}
BOOL WINAPI Handler(DWORD CtrlEvent) {
/* . */
ShutDown = TRUE;
return TRUE;
}