我正在尝试使用文件映射在C中构建客户端/服务器,但它仍处于开发初期,但在理解文件映射的工作原理时遇到了一些麻烦。
我在服务器上创建了一个结构的文件映射,并在上面放置了一些数据,然后我的客户端打开了文件映射,并读取了数据。然后,我的客户端将数据写入服务器以供读取,但服务器无法读取客户端数据,我也无法理解为什么,因为文件映射应该在两个进程之间进行同步。我现阶段仍未使用事件,但我认为它们不是工作所需的(是吗?)
她是我所拥有的代码。
服务器:
struct _HBACKUPSERVICE{
DWORD dwServerProcessID;
TCHAR szWork[MAX_PATH];
HANDLE hMapFile;
};
PHBACKUPSERVICE pBuf = NULL;
HANDLE hMapFile;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
sizeof(HBACKUPSERVICE), // maximum object size (low-order DWORD)
_T("MyService")); // name of mapping object
if (/*phBackupService->*/hMapFile == NULL){
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return *pBuf;
}
pBuf = (PHBACKUPSERVICE)MapViewOfFile(
hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(HBACKUPSERVICE));
if (pBuf == NULL){
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
return *pBuf;
}
// Populate backup service structure
pBuf->hMapFile = hMapFile;
pBuf->dwServerProcessID = GetCurrentProcessId();
// Wait for client
do{
_tprintf(_T("\nServer: Waiting for work."));
pBuf = (PHBACKUPSERVICE)MapViewOfFile(
_BackupService.hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(HBACKUPSERVICE));
if (StringCbLength(pBuf->szWork, 1 * sizeof(TCHAR), NULL) == S_OK){ Sleep(500); }
} while (StringCbLength(pBuf->szWork, 1 * sizeof(TCHAR), NULL) == S_OK); // ERROR: pBuf->szWork is always empty...
_tprintf(_T("Work from client: %s"), pBuf->szWork);
客户:
HBACKUPSERVICE _BackupService;
HANDLE hMapFile;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
_T("MyService")); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not open file mapping object (%d).\n"),
GetLastError());
}
BackupService= (PHBACKUPSERVICE)MapViewOfFile(
hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(HBACKUPSERVICE));
_tprintf(_T("Server process id: %d"), _BackupService.dwServerProcessID);
_tprintf(_T("send work to server"));
StringCchCopy(_BackupService.szWork, STRSAFE_MAX_CCH, _T("Do work for me!!!!!!!!!!")); //ERROR: the server never sees this
谢谢!
您的服务器正在MapViewOfFile()
其读取循环中进行调用,因此您正在映射越来越多的指针,而不是取消映射它们。最终,您将用完所有无法映射的地址。摆脱它。在进入循环之前,应该使用pBuf
从第一个指针获得的指针MapViewOfFile()
。您只需要映射一次视图。
您的客户端根本没有将数据写入映射视图,而是在写入局部HBACKUPSERVICE
变量而不是映射视图。这就是为什么服务器看不到数据的原因。
试试这个:
常见的:
typedef struct _HBACKUPSERVICE {
DWORD dwServerProcessID;
TCHAR szWork[MAX_PATH];
HANDLE hMapFile;
} HBACKUPSERVICE, *PHBACKUPSERVICE;
服务器:
PHBACKUPSERVICE pBuf = NULL;
HANDLE hMapFile;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
sizeof(HBACKUPSERVICE), // maximum object size (low-order DWORD)
_T("MyService")); // name of mapping object
if (hMapFile == NULL){
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return NULL;
}
pBuf = (PHBACKUPSERVICE)MapViewOfFile(
hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(HBACKUPSERVICE));
if (pBuf == NULL){
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
return NULL;
}
// Populate backup service structure
pBuf->hMapFile = hMapFile;
pBuf->dwServerProcessID = GetCurrentProcessId();
ZeroMemory(pBuf->szWork, sizeof(pBuf->szWork));
// Wait for client
_tprintf(_T("\nServer: Waiting for work."));
while (pBuf->szWork[0] == 0){ Sleep(500); }
_tprintf(_T("Work from client: %s"), pBuf->szWork);
客户:
PHBACKUPSERVICE BackupService = NULL;
HANDLE hMapFile;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
_T("MyService")); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not open file mapping object (%d).\n"),
GetLastError());
}
BackupService = (PHBACKUPSERVICE)MapViewOfFile(
hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(HBACKUPSERVICE));
if (BackupService == NULL){
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
}
_tprintf(_T("Server process id: %d"), BackupService->dwServerProcessID);
_tprintf(_T("send work to server"));
StringCchCopy(BackupService->szWork, MAX_PATH, _T("Do work for me!!!!!!!!!!"));
最后,TCHAR
对于跨过程边界的互操作是危险的。想象一下,如果ANSI应用程序尝试与UNICODE应用程序通信会发生什么。他们不同意您szWork
字段的格式,因此不同意您HBACKUPSERVICE
结构的字节大小。您应根据需要将其替换TCHAR
为CHAR
或WCHAR
,并使其两端保持一致。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句