| 列表3-1 TimeService服务范例 |
TimeClient应用程序范例
TimeClient范例程序(「03 TimeClient.exe」),在列表3-2中说明,用来测试TimeService服务。应用程序之原始码与资源档可在附赠光碟之03-TimeClient目录中找到。当您开始执行程序,会显示一个如图3-8所示的对话方块。
| 图3-8 在TimeClient范例应用程序之起始对话方块 |
为了察看客户端与服务器端之通讯,您必须在对话方块上方之编辑控制项中键入服务器的名称。如果您在同一个机器上执行客户端与服务器之处理程序,请键入如图3-8所示之句号并以其为伺服名称。当您按下Request Server’s Time之按钮时,客户端应用程序会呼叫CreateFile,以决定要连接哪一个服务器与客户端,并使服务器醒来并且处理客户端的要求。如果伺服端并没有执行,则CreateFile会执行失败并显示一个如图3-9所示之讯息方块。
| 图3-9 当TimeService没有执行时,经由TimeClient所显示之讯息方块 |
如果服务已经执行,CreateFile会回传一个有效的handle;而客户端会等待时间资料经由一个非同步呼叫ReadFile之管道传送回来。在客户端取得资料后,客户端的管道handle会被关闭,由服务器传送过来的时间会被转换成客户端的本地时间,并且会更新初始对话方块的内容,其结果如图3-10所示。
| 图3-10 TimeClient范例应用程序中被更新的对块方块内容 |
TimeClient.cpp
/************************************, ********************************
模组:TimeClient.cpp
通告:Copyright (c)2000 Jeffrey Richter
********************************************************************/
#include "..\CmnHdr.h" // 请参阅附录A
#include
#include "..\ClassLib\EnsureCleanup.h" // 请参阅附录B
#include "Resource.h"
//////////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
chSETDLGICONS(hwnd, IDI_TIMECLIENT);
// 假设服务与客户端程序在同一台机器上执行
SetDlgItemText(hwnd, IDC_SERVER, TEXT("."));
return(TRUE);
}
//////////////////////////////////////////////////////////////////////////////
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDOK:
// 建构管道的平台
TCHAR sz[500];
sz[0] = sz[1] = TEXT(’\\’);
GetDlgItemText(hwnd, IDC_SERVER, &sz[2], chDIMOF(sz) - 2);
lstrcat(sz, TEXT("\\pipe\\TimeService"));
// 尝试与管道连结
// 取得一个handle以与管道沟通
CEnsureCloseFile hpipe =
CreateFile(sz, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hpipe.IsValid()) {
// 有效的handle,从管道中读取时间
SYSTEMTIME st;
DWORD cbRead = 0;
ReadFile(hpipe, &st, sizeof(st), &cbRead, NULL);
// 转换UTC时间至客户端机器的本地时间并显示它
SystemTimeToTzSpecificLocalTime(NULL, &st, &st);
GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, sz,
chDIMOF(sz));
SetDlgItemText(hwnd, IDC_DATE, sz);
GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &st, NULL,
sz, chDIMOF(sz));
SetDlgItemText(hwnd, IDC_TIME, sz);
} else {
// 无效的handle,回执一个错误
SetDlgItemText(hwnd, IDC_DATE, TEXT("Error"));
SetDlgItemText(hwnd, IDC_TIME, TEXT("Error"));
// 取得错误的文字说明
HLOCAL hlocal = NULL; // 取得错误讯息字串之缓冲器
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (PSTR) &hlocal, 0, NULL);
if (hlocal != NULL) {
chMB((PCSTR)LocalLock(hlocal));
LocalFree(hlocal);
}
}
break;
}
}
//////////////////////////////////////////////////////////////////////////////
INT_PTR WINAPI Dlg_Proc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
}
return(FALSE);
}
//////////////////////////////////////////////////////////////////////////////
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {
DialogBox(hinstExe, MAKEINTRESOURCE(IDD_TIMECLIENT), NULL, Dlg_Proc);
return(0);
}
//////////////////////////////// End of File /////////////////////////////////
| 列表3-2 TimeClient范例应用程序 |
