/**//****************************************************************************** Module: Handshake.cpp Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #include "..\CmnHdr.h"/**//* See Appendix A. */ #include <windowsx.h> #include <tchar.h> #include <process.h>// For beginthreadex #include "Resource.h" /**//////////////////////////////////////////////////////////////////////////////// // This event is signaled when the client has a request for the server // 当客户端从服务器返回时该事件被通知(客户端将字符放入共享缓存时被通知) HANDLE g_hevtRequestSubmitted; // This event is signaled when the server has a result for the client // 当服务器完成翻转字符串时该事件被通知 HANDLE g_hevtResultReturned; // The buffer shared between the client and server threads // 客户端和服务器共享的缓存区 TCHAR g_szSharedRequestAndResultBuffer[1024]; // The special value sent from the client that causes the // server thread to terminate cleanly. // 客户端发送这个指定的值导致服务端线程终止 TCHAR g_szServerShutdown[] = TEXT("Server Shutdown"); /**//////////////////////////////////////////////////////////////////////////////// // This is the code executed by the server thread // 这些代码被服务器端线程执行 DWORD WINAPI ServerThread(PVOID pvParam) { // Assume that the server thread is to run forever //假设服务器端线程不会永远执行 BOOL fShutdown = FALSE; while (!fShutdown) { // Wait for the client to submit a request //等待事件对象通知 WaitForSingleObject(g_hevtRequestSubmitted, INFINITE); // Check to see if the client wants the server to terminate // 读取共享缓存区的值并与g_szServerShutdown比较,判断客户端线程是否要求服务器端线程终止运行 fShutdown = (lstrcmpi(g_szSharedRequestAndResultBuffer, g_szServerShutdown) ==0); //如果不是预定义的字符被传入,那么将进行翻转处理 if (!fShutdown) { // Process the client's request (reverse the string) _tcsrev(g_szSharedRequestAndResultBuffer); } // Let the client process the request's result //翻转处理完成,通知客户端线程来读取共享缓存区的内容 SetEvent(g_hevtResultReturned); } // The client wants us to shutdown, exit return(0); } /**//////////////////////////////////////////////////////////////////////////////// BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { //一个该死的宏,用来设置程序图标 chSETDLGICONS(hwnd, IDI_HANDSHAKE); // Initialize the edit control with some test data request //也是一个宏..用于设置文本框的初始值 Edit_SetText(GetDlgItem(hwnd, IDC_REQUEST), TEXT("Some test data")); return(TRUE); } /**//////////////////////////////////////////////////////////////////////////////// void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { //消息处理退出消息 case IDCANCEL: EndDialog(hwnd, id); break; //处理按钮点击消息 case IDC_SUBMIT: // Submit a request to the server thread // Copy the request string into the shared data buffer //获取文本框的值,第一个参数句柄,第二个缓存区,第三个要获取的长度 Edit_GetText(GetDlgItem(hwnd, IDC_REQUEST), g_szSharedRequestAndResultBuffer, chDIMOF(g_szSharedRequestAndResultBuffer)); // Let the server thread know that a request is ready in the buffer //将g_hevtRequestSubmitted置为通知状态使客户端线程可以读取缓存区内容 SetEvent(g_hevtRequestSubmitted); // Wait for the server to process the request and give us the result //等待服务器端线程翻转成功的事件通知并将结果文本框内容更新 WaitForSingleObject(g_hevtResultReturned, INFINITE); // Let the user know the result Edit_SetText(GetDlgItem(hwnd, IDC_RESULT), g_szSharedRequestAndResultBuffer); 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) { // Create & initialize the 2 nonsignaled, auto-reset events //自动重置的未通知状态的事件对象 g_hevtRequestSubmitted = CreateEvent(NULL, FALSE, FALSE, NULL); g_hevtResultReturned = CreateEvent(NULL, FALSE, FALSE, NULL); // Spawn the server thread //创建服务器线程 DWORD dwThreadID; HANDLE hThreadServer = chBEGINTHREADEX(NULL, 0, ServerThread, NULL, 0, &dwThreadID); // Execute the client thread's user-interface //哈哈这是一个模态的对话框,运行客户端线程的用户界面。 DialogBox(hinstExe, MAKEINTRESOURCE(IDD_HANDSHAKE), NULL, Dlg_Proc); // The client's UI is closing, have the server thread shutdown // 模态对话框退出以后,向服务器线程发送g_szServerShutdown // 并将g_hevtRequestSubmitted事件设为通知状态让服务器端线程运行(退出的代码) lstrcpy(g_szSharedRequestAndResultBuffer, g_szServerShutdown); SetEvent(g_hevtRequestSubmitted); // Wait for the server thread to acknowledge the shutdown AND // wait for the server thread to fully terminate // 等待服务器线程得到关闭通知并且完全关闭 HANDLE h[2]; h[0] = g_hevtResultReturned; h[1] = hThreadServer; WaitForMultipleObjects(2, h, TRUE, INFINITE); // Properly clean up everything CloseHandle(hThreadServer); //此时g_hevtRequestSubmitted依然为未通知状态因为是自动重置事件对象 //当服务器线程结束的时候它的内核对象变为通知状态,并且这种过程是不可逆的。 CloseHandle(g_hevtRequestSubmitted); CloseHandle(g_hevtResultReturned); // The client thread terminates with the whole process return(0); } /**///////////////////////////////// End of File //////////////////////////////////
posted on
2009-11-04 15:36wParma
阅读(936)
评论(2)
收藏举报