Помогите разобраться, не могу понять почему ядро вызывает COMPLETION_ROUTINE не дожидаясь новых данных в сокете?
Последовательность действий такая, листенер ожидает соединения, после соединения акцепт возвращает сокет, для этого сокета вызывается асинхронная ReadFileEx, дальше поток становится в ожидание в тревожном состоянии(alertable wait state — вызов SleepEx(INFINITE, true)).
Дальше поведение предсказуемо, когда в сокет поступают данные, ядро через APC, ставит в очередь IRP, поток просыпается и срабатывает CompletionRoutineReadfileex2, в котором читаем данные. Потом снова ставим для сокета ReadFileEx что бы ждать новых данных и тут или я не правильно понимаю принцип работы или надо сделать что то еще, но ядро вызывает колбэк(CompletionRoutineReadfileex2) сразу, не дожидаясь новых данных в сокете, тоесть приходит dwNumberOfBytesTransfered = 0 и так бесконечно.
По моему разумению, поток должен выйти и проснуться только тогда, когда будут новые данные. То есть, в COMPLETION_ROUTINE(CompletionRoutineReadfileex2) не происходит обнуление чего то и ядро считает что я не прочитал данные и снова вызывает колбэк.
CancelIo пробовал, не помогло.
#include "pch.h"
#include <iostream>
#include "SocketServerAPC01.h"
char sock_in_buf2[256];
int byte_available2;
void CALLBACK CompletionRoutineReadfileex2(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
byte_available2 = dwNumberOfBytesTransfered;
cout << "CompletionRoutineReadfileex ->> " << dwNumberOfBytesTransfered << " dwErrorCode ->" << dwErrorCode << endl;
Sleep(300);
ovpConnection *ov2 = (ovpConnection*)lpOverlapped;
memset(sock_in_buf2, 0, sizeof(sock_in_buf2));
unsigned long bw;
ovpConnection *ov3 = new ovpConnection;
memset(ov3, 0, sizeof(*ov3));
ov3->sock_handle = ov2->sock_handle;
ReadFileEx((HANDLE)ov3->sock_handle, sock_in_buf2, sizeof(sock_in_buf2), ov3, (LPOVERLAPPED_COMPLETION_ROUTINE)CompletionRoutineReadfileex2);
}
int main()
{
int err;
char buffer[128];
WORD wVersionRequested;
WSADATA wsaData;
SOCKET listen_socket;
LPFN_ACCEPTEX lpfn_accept;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err == SOCKET_ERROR)
{
strcpy_s(buffer, "Function error WSAStartup");
printf("%s %d\n", buffer, WSAGetLastError());
WSACleanup();
return 1;
}
listen_socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, WSA_FLAG_OVERLAPPED);
SOCKADDR_IN sinServer;
sinServer.sin_family = AF_INET;
sinServer.sin_port = htons(PORT);
sinServer.sin_addr.s_addr = INADDR_ANY;
err = bind(listen_socket, (LPSOCKADDR)&sinServer, sizeof(sinServer));
if (err == -1)
{
strcpy_s(buffer, "Function error bind");
printf("%s %d\n", buffer, GetLastError());
WSACleanup();
return 1;
}
err = listen(listen_socket, SOMAXCONN);
if (err == -1)
{
strcpy_s(buffer, "Function error listen №");
printf("%s %d\n", buffer, GetLastError());
WSACleanup();
return 1;
}
SOCKET accept_socket = accept(listen_socket, NULL, NULL);
ovpConnection *ov2 = new ovpConnection;
memset(ov2, 0, sizeof(*ov2));
ov2->sock_handle = accept_socket;
ReadFileEx((HANDLE)accept_socket, sock_in_buf2, sizeof(sock_in_buf2), ov2, (LPOVERLAPPED_COMPLETION_ROUTINE)CompletionRoutineReadfileex2);
DWORD dwWait;
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
std::cout << "Hello World!\n";
while (1) {
dwWait = SleepEx(INFINITE, true);
//dwWait = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
cout << "dwWait -> " << dwWait << endl;
}
return 0;
}
вывод на консоль:
CompletionRoutineReadfileex ->> 6 dwErrorCode ->0
dwWait -> 192
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
CompletionRoutineReadfileex ->> 0 dwErrorCode ->0
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Можно ли с помощью директивы #define заменить не одно слово на другое, а сразу кусок текста на другой кусок?
Подскажите, пожалуйста, возможно ли в C++ следующее:
Делаю стриминг сервис для вебинаровКогда пользователь заходит на страницу, он видит таймер и когда таймер подходит к концу - мне надо запустить...
Хотел сделать, чтобы при нажатии на стрелки класс -active переходил к предыдущей, либо к следующей кнопке slider__btnИ при нажатии на не активную кнопку...