IOCP Socket, не уверен, что делать дальше

Я научился создавать сокеты, используя Windows Message Proc, и включил FD_CONNECT, FD_ACCEPT, FD_CLOSE и т. Д. Я использовал: WSAAsyncSelect(socket, WindowHandle, WM_SOCKET, FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE | FD_ACCEPT),

Это дало мне знать, когда сокет: принимал, закрывал, получал данные без необходимости опроса.

Сейчас я пытаюсь научиться делать то же самое для консольных приложений, но с использованием IOCP.

Я написал следующее:

#include <Winsock2.h>
#include <Ws2tcpip.h>
#include <Windows.h>
#include <iostream>
#include <thread>
#include <stdexcept>
#include <cstring>

class Socket
{
private:
typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
char Buffer[1024];
unsigned int BytesSent;
unsigned int BytesReceived;
} PER_IO_OPERATION_DATA;

typedef struct
{
SOCKET Sock;
} PER_HANDLE_DATA;protected:
void Close();
std::function<void(HANDLE)> Worker;

public:
Socket();
bool Start(std::string Address, unsigned int Port, bool Listen);

void Read(char* Buffer, int bufflen); //reads from a socket.
void Write(char* Buffer, int bufflen); //writes to a socket.
bool Accept();  //accepts a socket.

virtual void OnRead();   //Called when Reading.
virtual void OnWrite();  //Called when Writing.
virtual void OnAccept(); //Called when a socket has been accepted.
virtual void OnConnect();  //Called when connected.
virtual void OnDisconnect(); //Called when disconnected.
};

bool Socket::Start(std::string Address, unsigned int Port, bool Listen)
{
WSADATA wsaData;
SOCKET sock = 0;
struct sockaddr_in* sockaddr_ipv4;

//WSA Startup and getaddrinfo, etc.. here..

//Create IOCP Handle and worker threads.
HANDLE IOCPPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
if (!IOCPPort)
{
this->Close();
throw std::runtime_error("Error: Creating IOCP Failed With Error: " + std::to_string(GetLastError()));
}

SYSTEM_INFO SystemInfo = {0};
GetSystemInfo(&SystemInfo);
for (std::size_t I = 0; I < SystemInfo.dwNumberOfProcessors * 2; ++I)
{
std::thread(this->Worker, IOCPPort).detach();
}

//Set the socket to overlapped.
if ((sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
this->Close();
throw std::runtime_error("Error: ");
}

struct sockaddr_in SockAddr;
std::memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_port = htons(Port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = (Address == "INADDR_ANY" ? htonl(INADDR_ANY) : inet_addr(Address.c_str()));

//If it is a server socket being created, bind it.
if (Listen && (bind(sock, reinterpret_cast<SOCKADDR*>(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR))
{
this->Close();
throw std::runtime_error("Error: ");
}

//If it is a server socket, start listenening.
if (Listen && (listen(sock, SOMAXCONN) == SOCKET_ERROR))
{
this->Close();
throw std::runtime_error("Error: ");
}

//Otherwise it is a client socket so just connected..
//if(!Listen && (connect(this->socket, reinterpret_cast<SOCKADDR*>(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR))//Associate this socket with a completion port.
if (CreateIoCompletionPort(reinterpret_cast<HANDLE>(sock), IOCPPort, 0, 0) != IOCPPort)
{
this->Close();
throw std::runtime_error("Error: ");
}

//setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)sdListen, sizeof(sdListen));
}

Однако сейчас я застрял. Я не уверен, что мне нужно делать после создания IoCompletionPort. Как узнать, когда сокет принят, чтобы я мог вызвать OnAccept или как узнать, когда есть данные для чтения, чтобы я мог вызвать OnRead? Я просмотрел все страницы в Google и не могу найти ничего похожего на OnRead, OnAccept или OnWrite.

Я просто хочу сделать его масштабируемым и иметь обратные вызовы, когда что-то происходит без использования событий или цикла сообщений. Единственная вещь, которую я увидел в Google, которая заинтересовала меня, была IOCP, но я полностью потерян. Есть идеи, что мне нужно делать дальше?

1

Решение

Я написал несколько статей о дизайне IOCP-сервера давным-давно, и у меня также есть некоторый код, который вы можете скачать, который делает основы для вас.

Вы можете получить код и найти ссылки на статьи из Вот. Они могут помочь вам понять, что происходит дальше и как структурировать клиент или сервер IOCP.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]