IOCP 套接字,不知道下一步该做啥

Posted

技术标签:

【中文标题】IOCP 套接字,不知道下一步该做啥【英文标题】:IOCP Socket, Not sure what to do nextIOCP 套接字,不知道下一步该做什么 【发布时间】:2013-11-09 22:41:46 【问题描述】:

我学习了如何使用 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 的任何内容。

我只是想让它具有可扩展性,并在不使用事件或消息循环的情况下在发生某些事情时进行回调。我在谷歌上看到的唯一让我感兴趣的是 IOCP,但我完全迷路了。有什么想法我接下来需要做什么吗?

【问题讨论】:

TBH,我也不知道下一步该做什么。也许明天,当我清醒过来的时候。同时,你能发布'this->Worker'的代码吗? 【参考方案1】:

我很久以前写过一些关于 IOCP 服务器设计的文章,我也有一些代码可以下载,这些代码可以为你提供基础知识。

您可以从here 获取代码并找到文章的链接。它们可以帮助您了解接下来会发生什么以及如何构建 IOCP 客户端或服务器。

【讨论】:

以上是关于IOCP 套接字,不知道下一步该做啥的主要内容,如果未能解决你的问题,请参考以下文章

Beta 测试 Android 应用程序

应用因指南 3.2 - 业务而被拒绝,下一步该怎么做?

一个只有99行代码的JS流程框架

可绘制到字节[]

转行软件测试两个多月,感觉很迷茫,下一步该如何提高自己?

C ++中的无效间接