Как заставить GetQueuedCompletionStatus() возвращать любое значение после вызова AcceptEd()?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как заставить GetQueuedCompletionStatus() возвращать любое значение после вызова AcceptEd()?

Сообщение Anonymous »


Проблема в том, что GetQueuedCompletionStatus() никогда не возвращает никакого значения после завершения AcceptEx(), с другой стороны, другого GetQueuedCompletionStatus() дает значение true после вызова ConnectEx().

Я не знаю, почему ConnectEx() с GetQeuedCompletionStatus() работает, а AcceptEx() — нет.
>
Я что-то упустил?

Мой код ниже:

КОД СЕРВЕРА: GetQueuedCompletionStatus() никогда не возвращает TRUE или FALSE.
#прагма один раз #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "mswsock.lib") #include #include #include #include #include #include #include #include constexpr const USHORT ПОРТ = 1501; constexpr const INT MAXIMUM_BACKLOG = 1501; constexpr const INT MAXIMUM_BUFFER = 1024; интервал основной() { ВСАДАТА wsaData{}; ::memset(&wsaData, NULL, sizeof(wsaData)); SOCKET ListenSocket = INVALID_SOCKET; SOCKET AcceptSocket = INVALID_SOCKET; SOCKADDR_IN ListenAddress {}; ::memset(&listenAddress, NULL, sizeof(listenAddress)); HANDLE ListenHandle = INVALID_HANDLE_VALUE; BOOL SocketOption = ИСТИНА; буфер символов [MAXIMUM_BUFFER] {}; ::memset(&buffer, NULL, sizeof(buffer)); WSAOVERLAPPED перекрыт1{}; ::memset(&overlapped1, NULL, sizeof(overlapped1)); WSAOVERLAPPED перекрыто2{}; ::memset(&overlapped2, NULL, sizeof(overlapped2)); DWORD байт1 = NULL; DWORD байт2 = NULL; ULONG_PTR ключ завершения = NULL; if (NULL != ::WSAStartup(MAKEWORD(2, 2), &wsaData)) вернуть НУЛЬ; ListenHandle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, (HANDLE)NULL, (ULONG_PTR)NULL, (DWORD)NULL); если (NULL == ListenHandle) { ::WSACleanup(); вернуть НУЛЬ; } ListenSocket = ::WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, (LPWSAPROTOCOL_INFOW)nullptr, (GROUP)NULL, WSA_FLAG_OVERLAPPED); если (INVALID_SOCKET == ListenSocket) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } ListenAddress.sin_addr.S_un.S_addr = ::htonl(INADDR_ANY); ListenAddress.sin_family = AF_INET; ListenAddress.sin_port = ::htons(ПОРТ); if (SOCKET_ERROR == ::bind(listenSocket, (const SOCKADDR*)&listenAddress, sizeof(listenAddress))) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } если (SOCKET_ERROR == ::listen(listenSocket, MAXIMUM_BACKLOG)) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } if (FALSE == ::setsockopt(listenSocket, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (const char*)&socketOption, sizeof(socketOption))) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } если (NULL == ::CreateIoCompletionPort((HANDLE)listenSocket, ListenHandle, (ULONG_PTR)NULL, (DWORD)NULL)) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } AcceptSocket = ::WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, (LPWSAPROTOCOL_INFOW)nullptr, (GROUP)NULL, WSA_FLAG_OVERLAPPED); если (INVALID_SOCKET == AcceptSocket) { :: closesocket (listenSocket); :: closesocket (acceptSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } if (FALSE == ::AcceptEx(listenSocket, AcceptSocket, (PVOID)&buffer, (DWORD)NULL, (DWORD)sizeof(SOCKADDR_IN) + 16, (DWORD)sizeof(SOCKADDR_IN) + 16, (LPDWORD)&bytes1, (LPOVERLAPPED)&перекрытие1)) { если (WSA_IO_PENDING != ::WSAGetLastError()) { :: closesocket (listenSocket); :: closesocket (acceptSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } } if (FALSE == ::GetQueuedCompletionStatus(listenHandle, (LPDWORD)&bytes2, (PULONG_PTR)&completionKey, (LPOVERLAPPED*)&overlapped2, WSA_INFINITE)) { :: closesocket (listenSocket); :: closesocket (acceptSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } вернуть НУЛЬ; }
КЛИЕНТ: После вызова ConnectExLPFN обработка GetQueuedCompletionStatus() аналогичным образом на стороне SERVER возвращает TRUE.
#прагма один раз #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "mswsock.lib") #include #include #include #include #include #include #include #include constexpr const USHORT ПОРТ = 1501; constexpr const INT MAXIMUM_BACKLOG = 1501; constexpr const INT MAXIMUM_BUFFER = 1024; интервал основной() { ВСАДАТА wsaData{}; ::memset(&wsaData, NULL, sizeof(wsaData)); SOCKET ListenSocket = INVALID_SOCKET; SOCKADDR_IN ListenAddress {}; ::memset(&listenAddress, NULL, sizeof(listenAddress)); HANDLE ListenHandle = INVALID_HANDLE_VALUE; BOOL SocketOption = ИСТИНА; буфер символов [MAXIMUM_BUFFER] {}; ::memset(&buffer, NULL, sizeof(buffer)); WSAOVERLAPPED перекрыт1{}; ::memset(&overlapped1, NULL, sizeof(overlapped1)); WSAOVERLAPPED перекрыто2{}; ::memset(&overlapped2, NULL, sizeof(overlapped2)); DWORD байт1 = NULL; DWORD байт2 = NULL; ULONG_PTR ключ завершения = NULL; GUID ConnectExGUID = WSAID_CONNECTEX; LPFN_CONNECTEX ConnectExLPFN {}; ::memset(&connectExLPFN, NULL, sizeof(connectExLPFN)); if (NULL != ::WSAStartup(MAKEWORD(2, 2), &wsaData)) вернуть НУЛЬ; ListenHandle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, (HANDLE)NULL, (ULONG_PTR)NULL, (DWORD)NULL); если (NULL == ListenHandle) { ::WSACleanup(); вернуть НУЛЬ; } ListenSocket = ::WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, (LPWSAPROTOCOL_INFOW)nullptr, (GROUP)NULL, WSA_FLAG_OVERLAPPED); если (INVALID_SOCKET == ListenSocket) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } if (SOCKET_ERROR == ::InetPtonW(AF_INET, (PCWSTR)L"127.0.0.1", (PVOID)&listenAddress)) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } ListenAddress.sin_family = AF_INET; ListenAddress.sin_port = ::htons(ПОРТ); if (SOCKET_ERROR == ::bind(listenSocket, (const SOCKADDR*)&listenAddress, sizeof(listenAddress))) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } если (NULL == ::CreateIoCompletionPort((HANDLE)listenSocket, ListenHandle, (ULONG_PTR)NULL, (DWORD)NULL)) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } if (SOCKET_ERROR == ::WSAIoctl(listenSocket, SIO_GET_EXTENSION_FUNCTION_POINTER, (LPVOID)&connectExGUID, sizeof(connectExGUID), (LPVOID)&connectExLPFN, sizeof(connectExLPFN), (LPDWORD)&bytes1, (LPWSAOVERLAPPED)&overlapped1, (LPWSAOVERLAPPED_COMP) LETION_ROUTINE)nullptr)) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } if (FALSE == connectExLPFN(listenSocket, (const SOCKADDR*)&listenAddress, sizeof(listenAddress),(PVOID)&buffer, sizeof(buffer),(LPDWORD)&bytes2,(LPOVERLAPPED)&overlapped2)) { если (WSA_IO_PENDING != ::WSAGetLastError()) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } } if (FALSE == ::GetQueuedCompletionStatus(listenHandle, (LPDWORD)&bytes2, (PULONG_PTR)&completionKey, (LPOVERLAPPED*)&overlapped2, WSA_INFINITE)) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } if (FALSE == ::setsockopt(listenSocket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, (const char*)&socketOption, sizeof(socketOption))) { :: closesocket (listenSocket); ::CloseHandle(listenHandle); ::WSACleanup(); вернуть НУЛЬ; } вернуть НУЛЬ; }
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»