Утечка информации при WriteFile
23.02.2017, 12:27. Показов 509. Ответов 0
Есть у меня client-server named pipe коммуникация. Если сервер стартует до того, как клиент ему старается что-то отправить, то все нормально. Но если же клиент пробует это делать до того, как сервер стартует, то клиет в цикле стучится к серверу через CreateFile, пока тот INVALID_HANDLE_VALUE. Когда он наконец дождался, то шлет сообщение. И WriteFile возвращает TRUE, и в GetOverlappedResult я получаю bytesWritten == 24, что соответствует обьему L"Hello World!". Но сервер никак не реагирует на ивент и до ReadFile у него не доходит. Когда я повторно запущу клиент, то все ОК приходит. Куда пропал первый текст? Подскажите, где проблема.
Клиент:
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
| PIPE_RESULT PipeClient::connect()
{
Timer timer(TIMEOUT::LARGE);
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
while (timer.in() && pipeHandle == INVALID_HANDLE_VALUE)
{
pipeHandle = CreateFile(pipe.getName().c_str(), GENERIC_READ | GENERIC_WRITE, 0 , NULL, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED, NULL);
DWORD lasterr = GetLastError();
int x = 1;
}
if (pipeHandle == INVALID_HANDLE_VALUE)
{
return PIPE_RESULT::INVALID_HANDLE;
}
if (GetLastError() == ERROR_PIPE_BUSY)
{
if (!WaitNamedPipe(pipe.getName().c_str(), timer.timeLeft()))
{
return PIPE_RESULT::BUSY;
}
}
pipe.setHandle(pipeHandle);
return PIPE_RESULT::SUCCESS;
}
PIPE_RESULT PipeClient::sendMessage(const std::wstring& message)
{
if (message.empty())
{
return PIPE_RESULT::INVALID_MESSAGE;
}
PIPE_RESULT result = connect();
if (!Succeeded(result))
{
return result;
}
DWORD bytesWritten;
OVERLAPPED ov;
ZeroMemory(&ov, sizeof(ov));
ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if (!WriteFile(pipe(), message.c_str(), message.size() * sizeof(TCHAR), &bytesWritten, &ov))
{
return PIPE_RESULT::WRITE_FILE_ERROR;
}
DWORD lastErr = GetLastError();
DWORD bytesTransferred;
GetOverlappedResult(pipe(), &ov, &bytesTransferred, TRUE);
DWORD lasterr2 = GetLastError();
return PIPE_RESULT::SUCCESS;
} |
|
Сервер:
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
| PIPE_RESULT PipeServer::start()
{
pipe.setHandleSafe(
CreateNamedPipe(pipe.getName().c_str()
, PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | FILE_FLAG_OVERLAPPED
, PIPE_WAIT, 1, 1024 * 16, 1024 * 16, NMPWAIT_USE_DEFAULT_WAIT, NULL)); // todo replace magic nums
ZeroMemory(&ov, sizeof(OVERLAPPED));
ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (ov.hEvent == NULL)
{
return PIPE_RESULT(); //todo error
}
if (!ConnectNamedPipe(pipe(), &ov))
{
if (GetLastError() != ERROR_IO_PENDING)
{
return PIPE_RESULT();
}
}
threadPtr.reset(new std::thread(&PipeServer::startListeting, this));
return PIPE_RESULT::SUCCESS;
}
void PipeServer::startListeting()
{
std::wstring message;
DWORD Ret;
while (true)
{
if ((Ret = WaitForSingleObject(ov.hEvent, TIMEOUT::HALF_SECOND)) == WAIT_FAILED)
{
return;
}
ResetEvent(ov.hEvent);
BOOL pingPipe = FALSE;
Ret = 0;
Timer timer(1000);
while (!pingPipe || !Ret)
{
pingPipe = PeekNamedPipe(pipe(), NULL, 0, NULL, &Ret, NULL);
}
if (!pingPipe || !Ret)
{
return;
}
message.resize(Ret / sizeof(TCHAR) + 1);
if (ReadFile(pipe(), &message[0], Ret, NULL, &ov) == 0)
{
DWORD lastErr = GetLastError();
if (GetLastError() != ERROR_IO_PENDING)
{
printf("ReadFile failed with error %d\n",
GetLastError());
}
}
else
{
DWORD lastErr = GetLastError();
std::wstring responce;
processMessage(message, responce);
std::wcout << responce << std::endl;
}
DisconnectNamedPipe(pipe());
ZeroMemory(&ov, sizeof(OVERLAPPED));
ov.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
if (!ConnectNamedPipe(pipe(), &ov))
{
if (GetLastError() != ERROR_IO_PENDING)
{
return;
}
}
}
}
PIPE_RESULT PipeServer::processMessage(const std::wstring& msg, std::wstring& responce)
{
responce.assign(msg);
return PIPE_RESULT::SUCCESS;
} |
|
0
|