WaitNamedPipe CreateFile. , , , socket , connect .
, connect , ConnectNamedPipe .
:
. 11, . , , . ReceiveMessage, . SendMessage, .
, : . , MESSAGE 4- . 4- recv, , recv .
, Win64
, , LONG32, , , Windows, Win64 (. 16).
DWORD ReceiveMessage (MESSAGE *pMsg, SOCKET sd) {
/* 4- , . */
DWORD Disconnect = 0;
LONG32 nRemainRecv, nXfer;
LPBYTE pBuffer;
/* . */
/* , . */
nRemainRecv = 4; /* . */
pBuffer = (LPBYTE)pMsg; /* recv . */
while (nRemainRecv > 0 &&!Disconnect) {
nXfer = recv(sd, pBuffer, nRemainRecv, 0);
Disconnect = (nXfer == 0);
nRemainRecv =nXfer;
pBuffer += nXfer;
}
/* . */
nRemainRecv = pMsg->RqLen;
while (nRemainRecv > 0 &&!Disconnect) {
nXfer = recv(sd, pBuffer, nRemainRecv, 0);
Disconnect = (nXfer == 0);
nRemainRecv =nXfer;
pBuffer += nXfer;
}
return Disconnect;
}
:
12.1 clientNP ( 11.2), . .
IP- . IP- , 127.0.0.1, .
|
|
, , ReceiveMessage, .
, SERVER_PORT, ClntSrvr.h.
Windows, Windows , WSA.
12.1. clientSK:
/* 12. clientSK. */
/* . */
/* WINDOWS SOCKETS. */
/* */
/* . . */
#define _NOEXCLUSIONS /* . */
#include "EvryThng.h"
#include "ClntSrvr.h" /* . */
/* . */
/* , ReceiveResponseMessage . */
static DWORD SendRequestMessage(REQUEST *, SOCKET);
static DWORD ReceiveResponseMessage(RESPONSE *, SOCKET);
struct sockaddr_in ClientSAddr; /* . */
int _tmain(DWORD argc, LPTSTR argv[]) {
SOCKET ClientSock = INVALID_SOCKET;
REQUEST Request; /* . ClntSrvr.h. */
RESPONSE Response; /* . ClntSrvr.h. */
WSADATA WSStartData; /* . */
BOOL Quit = FALSE;
DWORD ConVal, j;
TCHAR PromptMsg[] = _T("\n > ");
TCHAR Req[MAX_RQRS_LEN];
TCHAR QuitMsg[] = _T("$Quit");
/* : . */
TCHAR ShutMsg[] = _T("$ShutDownServer"); /* . */
CHAR DefaultIPAddr[] = "127.0.0.1"; /* . */
/* WSA; 2.0, 1.1. */
WSAStartup(MAKEWORD(2, 0), &WSStartData);
/* . */
/* socket/connect . */
ClientSock = socket(AF_INET, SOCK_STREAM, 0);
memset(&ClientSAddr, 0, sizeof(ClientSAddr));
ClientSAddr.sin_family = AF_INET;
if (argc >= 2) ClientSAddr.sin_addr.s_addr = inet_addr(argv [1]);
else ClientSAddr.sin_addr.s_addr = inet_addr(DefaultIPAddr);
ClientSAddr.sin_port = htons(SERVER_PORT);
/* 1070. */
connect(ClientSock, (struct sockaddr *)&ClientSAddr, sizeof(ClientSAddr));
/* , . */
while (!Quit) {
_tprintf(_T("%s"), PromptMsg);
/* , ASCII. */
_fgetts(Req, MAX_RQRS_LEN-1, stdin);
for (j = 0; j <= _tcslen(Req) Request.Record[j] = Req[j];
/* . */
Request.Record[strlen(Request.Record) 1] = '\0';
if (strcmp(Request.Record, QuitMsg) == 0 || strcmp(Request.Record, ShutMsg) == 0) Quit = TRUE;
SendRequestMessage(&Request, ClientSock);
ReceiveResponseMessage(&Response, ClientSock);
}
shutdown(ClientSock, 2); /* . */
closesocket(ClientSock);
|
|
WSACleanup();
_tprintf(_T("\n**** \n"));
return 0;
}
:
serverSK ( 12.2) serverNP ( 11.3), .
(on demand), . , , , , .
(accept thread), , accept . , . , Winsock , Windows .
, .
(in-process servers), DLL . DLL , DLL. DLL; , serverNP. DLL 12.3. DLL , DLL .
serverNP. , , .
Windows , , , , , Windows.
12.2. serverSK:
/* 12. - . . . */
/* . */
/* , */
/* , . */
/* : argv [1] */
/* DLL, . */
#define _NOEXCLUSIONS
#include "EvryThng.h"
#include "ClntSrvr.h" /* . */
struct sockaddr_in SrvSAddr;
/* . */
struct sockaddr_in ConnectSAddr; /* . */
WSADATA WSStartData; /* . */
typedef struct SERVER_ARG_TAG { /* . */
volatile DWORD number;
volatile SOCKET sock;
volatile DWORD status;
/* . */
volatile HANDLE srv_thd;
HINSTANCE dlhandle; /* . */
} SERVER_ARG;
volatile static ShutFlag = FALSE;
static SOCKET SrvSock, ConnectSock;
int _tmain(DWORD argc, LPCTSTR argv[]) {
/* . */
BOOL Done = FALSE;
DWORD ith, tstatus, ThId;
SERVER_ARG srv_arg[MAX_CLIENTS];
HANDLE hAcceptTh = NULL;
HINSTANCE hDll = NULL;
|
|
/* WSA; 2.0, 1.1. */
WSAStartup(MAKEWORD(2, 0), &WSStartData);
/* , . */
if (argc > 1) hDll = LoadLibrary(argv[1]);
/* arg . */
for (ith = 0; ith < MAXCLIENTS; ith++) {
srv_arg[ith].number = ith;
srv_arg[ith].status = 0;
srv_arg[ith].sock = 0;
srv_arg[ith].dlhandle = hDll;
srv_arg[ith].srv_thd = NULL;
}
/* socket/bind/listen/accept . */
SrvSock = socket(AF_INET, SOCK_STREAM, 0);
SrvSAddr.sin_family = AF_INET;
SrvSAddr.sin_addr.s_addr = htonl(INADDR_ANY);
SrvSAddr.sin_port = htons(SERVER_PORT);
bind(SrvSock, (struct sockaddr *)&SrvSAddr, sizeof SrvSAddr);
listen(SrvSock, MAX_CLIENTS);
/* //.*/
/* arg . */
/* : 0 ; 1 ; 2 ; 3 . */
while (!ShutFlag) {
for (ith = 0; ith < MAX_CLIENTS &&!ShutFlag;) {
if (srv_arg[ith].status==1 || srv_arg[ith].status==3) { /* , . */
WaitForSingleObject(srv_arg[ith].srv_thd INFINITE);
CloseHandle(srv_arg[ith].srv_tnd);
if (srv_arg[ith].status == 3) ShutFlag = TRUE;
else srv_arg[ith].status = 0;
/* . */
}
if (srv_arg[ith].status == 0 || ShutFlag) break;
ith = (ith + 1) % MAXCLIENTS;
if (ith == 0) Sleep(1000);
/* . */
/* : , . */
}
/* . */
/* ShutFlag. */
hAcceptTh = (HANDLE)_beginthreadex(NULL, 0, AcceptTh, &srv_arg[ith], 0, &ThId);
while (!ShutFlag) {
tstatus = WaitForSingleObject(hAcceptTh, CS_TIMEOUT);
if (tstatus == WAIT_OBJECT_0) break; /* . */
}
CloseHandle(hAcceptTh);
hAcceptTh = NULL; /* . */
}
_tprintf(_T(" . \n"));
/* , . */
/* */
/* Web- . */
if (hDll!= NULL) FreeLibrary(hDll);
if (hAcceptTh!= NULL) TerminateThread(hAcceptTh, 0);
/* . */
for (ith = 0; ith < MAXCLIENTS; ith++) if (srv_arg [ith].status!= 0) {
WaitForSingleObject(srv_arg[ith].srv_thd, INFINITE);
CloseHandle(srv_arg[ith].srv_thd);
}
shutdown(SrvSock, 2);
closesocket(SrvSock);
WSACleanup();
return 0;
}
static DWORD WINAPI AcceptTh(SERVER_ARG * pThArg) {
/* , . , . */
LONG AddrLen, ThId;
AddrLen = sizeof(ConnectSAddr);
pThArg->sock = accept(SrvSock, /* . */
(struct sockaddr *)&ConnectSAddr, &AddrLen);
/* . . */
pThArg->status = 2;
pThArg->srv_thd = (HANDLE)_beginthreadex (NULL, 0, Server, pThArg, 0, &ThId);
return 0; /* . */
}
static DWORD WINAPI Server(SERVER_ARG * pThArg)
/* . . */
|
|
{
/* , . */
/* serverNP */
SOCKET ConnectSock;
int Disconnect = 0, i;
int (*dl_addr)(char *, char *);
char *ws = " \0\t\n"; /* . */
GetStartupInfo(&StartInfoCh);
ConnectSock = pThArg->sock;
/* . */
sprintf(TempFile, "%s%d%s", "ServerTemp", pThArg->number, ".tmp");
while (!Done &&!ShutFlag) { /* . */
Disconnect = ReceiveRequestMessage(&Request, ConnectSock);
Done = Disconnect || (strcmp(Request.Record, "$Quit") == 0) || (strcmp(Request.Record, "$ShutDownServer") == 0);
if (Done) continue;
/* "$Quit" "$ShutDownServer". */
hTrapFile = CreateFile(TempFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &TempSA, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
/* DLL. */
/* */
/* . , .*/
i = strcspn(Request.Record, ws); /* . */
memcpy(sys_command, Request.Record, i);
sys_command[i] = '\0';
dl_addr = NULL; /* GetProcAddress. */
if (pThArg->dlhandle!= NULL) {/* "" . */
dl_addr = (int (*)(char *, char *))GetProcAddress(pThArg->dlhandle, sys_command);
if (dl_addr!= NULL) __try {
/* , DLL*/
(*dl_addr)(Request.Record, TempFile);
} __except (EXCEPTION_EXECUTE_HANDLER) {
ReportError(_T(" DLL"), 0, FALSE);
}
}
if (dl_addr == NULL) { /* . */
/* . */
/* , serverNP */
}
/* , serverNP */
} /* . . */
/* . ; . */
_tprintf(_T(" # %d\n"), pThArg->number);
shutdown(ConnectSock, 2);
closesocket(ConnectSock);
pThArg->status = 1;
if (strcmp(Request.Record, "$ShutDownServer") == 0) {
pThArg->status = 3;
ShutFlag = TRUE;
}
return pThArg->status;
}