?? server.c
字號:
MessageBox (*hWnd, errorBuf, lpBuffer,
MB_ICONINFORMATION | MB_OK | MB_APPLMODAL);
};
// Block until a client connects.
ConnectNamedPipe(hPipe, NULL);
// Create and init overlap for writing.
hEventWrt = CreateEvent (NULL, TRUE, FALSE, NULL);
memset (&OverLapWrt, 0, sizeof(OVERLAPPED));
OverLapWrt.hEvent = hEventWrt;
// Set the clientIndex, then increment
// the count. Fill in the structure
// for this client in the array.
clientIndex = clientCount++;
clients[clientIndex].hPipe = hPipe;
clients[clientIndex].live = TRUE;
clients[clientIndex].overLap = OverLapWrt;
clients[clientIndex].hEvent = hEventWrt;
// Create and init overlap for reading.
hEventRd = CreateEvent(NULL,TRUE,FALSE,NULL);
memset (&OverLapRd, 0, sizeof(OVERLAPPED));
OverLapRd.hEvent = hEventRd;
// Read from the client, the first
// first message should always be
// the clients user name.
retCode = ReadFile (hPipe, inBuf, PLEASE_READ, &bytesRead, &OverLapRd);
if (!retCode)
lastError = GetLastError();
if (lastError == ERROR_IO_PENDING) // Wait on read if need be.
WaitForSingleObject (hEventRd, (DWORD)-1);
// Put client's name in the array.
strcpy (clients[clientIndex].Name, inBuf);
// Create a thread which will make
// another server instance of the
// named pipe.
CreateThread ((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)ServerProc, // Thread procedure.
(LPVOID)hWnd, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ServerThreadID); // Thread identifier.
TellAll(""); // Forces a paint, draws a red spool
// and name for this client.
// Do loop which basically reads from
// this specific client, and then
// uses TellAll() to broadcast the
// message to all the connected
// clients.
do{
// Read the pipe.
retCode = ReadFile (hPipe, inBuf, PLEASE_READ, &bytesRead, &OverLapRd);
// Check for three kinds of errors:
// If Error = IO_PENDING, wait til
// the event handle signals success,
// If BROKEN_PIPE, exit the do loop.
// Any other error, flag it to the
// user and exit the do loop.
if (!retCode)
{
lastError = GetLastError();
switch (lastError)
{
// IO_PENDING, wait on the event.
case ERROR_IO_PENDING:
WaitForSingleObject (hEventRd, (DWORD)-1);
break;
// Pipe is broken, exit the loop.
case ERROR_BROKEN_PIPE:
ExitLoop = TRUE;
break;
// Something else is wrong, exit the
// the loop after telling the user.
default:
LoadString(hInst, IDS_READERROR, lpBuffer, sizeof(lpBuffer));
wsprintf (errorBuf, lpBuffer, lastError);
LoadString(hInst, IDS_DEBUGINFO, lpBuffer, sizeof(lpBuffer));
MessageBox (*hWnd, errorBuf, lpBuffer, MB_OK);
ExitLoop = TRUE;
break;
}
}
if (!ExitLoop)
{
GetOverlappedResult (hPipe, &OverLapRd, &bytesTransRd, FALSE);
// Use TellAll to broadcast the message.
if (bytesTransRd)
TellAll(inBuf);
else
TellAll("");
}
}while(!ExitLoop);
clients[clientIndex].live = FALSE; // Turns spool gray.
CloseHandle (hPipe); // Close handles.
CloseHandle (hEventRd);
CloseHandle (hEventWrt);
DisconnectNamedPipe (hPipe); // Close pipe instance.
ExitThread(0); // Clean up and die.
}
/* To write the buffer (input parameter) to all of the clients listed
in the global array "clients". Clients is a global array which hold information on each client
connected to the named pipe. This procedure recieves a buffer.
It then steps through this global array, and for each client it
writes the buffer. */
VOID TellAll( CHAR *buffer )
{
DWORD i; // Index through array.
DWORD bytesWritten; // Used in WriteFile().
DWORD retCode; // Traps return codes.
CHAR Buf[LINE_LEN]; // Message Buffer.
DWORD lastError; // Traps returns from GetLastError().
for(i=0; i < clientCount; i++) // For all clients in the array.
{
// If client isn't alive, don't waste
// time writing to it.
if (clients[i].live)
{
retCode = WriteFile (clients[i].hPipe, buffer, strlen(buffer),
&bytesWritten, &clients[i].overLap);
// Check 3 kinds of errors: IO_PENDING,
// NO_DATA, or other. Wait on event
// handle if IO_PENDING, else, if it's
// anything other than NO_DATA (pipe
// client disconnected), flag the user.
// In any case, if it's not IO_PENDING,
// clients[i].live = FALSE, spool turns
// gray.
if (!retCode)
{
lastError = GetLastError();
// IO_PENDING, wait on event handle.
if (lastError == ERROR_IO_PENDING)
{
WaitForSingleObject (clients[i].hEvent, (DWORD)-1);
}
else
{
// If not NO_DATA, flag user.
if (lastError != ERROR_NO_DATA)
{
LoadString(hInst, IDS_DEBUGLAST, lpBuffer, sizeof(lpBuffer));
wsprintf (Buf, "%s = %d", buffer, GetLastError());
MessageBox(hWnd, Buf, lpBuffer, MB_OK);
}
clients[i].live = FALSE;
}
}
} //if client.live
} // for loop
// Paint window with new information.
InvalidateRect(hWnd, NULL, TRUE);
}
/*
To draw one of four bitmaps for each client, depending upon the clients
status (alive = red spool, dead or disconnected = gray), and location in
the array. It also draws the clients user name beside the spool.
This procedure is executed when the WM_PAINT message is trapped. */
VOID DrawBranch(HDC hDC)
{
// Spool bitmaps.
HBITMAP hEndLive, hEndDead, hMidLive, hMidDead, hBitMap;
HDC hDCMem;
int X, Y;
BITMAP bm;
POINT ptSize, ptOrg;
DWORD index;
// Load bitmaps: two red (live),
// two dead (gray). End = end
// of tree (last client to connect),
// mid means in the middle somewhere.
hEndLive = LoadBitmap (hInst, "EndLive");
hEndDead = LoadBitmap (hInst, "EndDead");
hMidLive = LoadBitmap (hInst, "MidLive");
hMidDead = LoadBitmap (hInst, "MidDead");
// For each client, determine if
// if alive or not, and position;
// then blt appropriate map and
// clients name.
for (index = 0; index < clientCount; index++)
{
if (index < clientCount - 1) // ClientCount - 1 = last (end) client.
{
if(clients[index].live) // If live = red, else = gray.
hBitMap = hMidLive;
else
hBitMap = hMidDead;
}
else
{
if(clients[index].live) // If live = red, else = gray.
hBitMap = hEndLive;
else
hBitMap = hEndDead;
}
// Calculate coordinates:
X = BITMAP_X; // X position is constant.
Y = index * BITMAP_Y; // Y is based on index in the array.
// Blt the chosen map.
hDCMem = CreateCompatibleDC(hDC);
SelectObject(hDCMem, hBitMap);
SetMapMode(hDCMem, GetMapMode(hDC));
GetObject(hBitMap, sizeof(BITMAP), &bm);
ptSize.x = bm.bmWidth;
ptSize.y = bm.bmHeight;
DPtoLP (hDC, &ptSize, 1);
ptOrg.x = 0;
ptOrg.y = 0;
DPtoLP (hDCMem, &ptOrg, 1);
BitBlt(hDC, X, Y, ptSize.x, ptSize.y,
hDCMem, ptOrg.x, ptOrg.y, SRCCOPY);
X = NAME_X; // Relocate X,Y for clients name.
Y += NAME_Y;
// Write name next to spool.
TextOut (hDC, X, Y, clients[index].Name, strlen(clients[index].Name));
DeleteDC(hDCMem);
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -