c++ - 如何使 WSAAsyncSelect 在应用程序控制台中启动?

标签 c++ sockets winapi

我一直在尝试学习如何在 C++ 中使用套接字,所以我搜索了一个教程,我读了它,教程说有两种方法从套接字接收信息,第一种是通过无限循环不断检查recv,另一个正在使用异步套接字,我尝试使用异步,但收到错误10022,我搜索了该错误,它说函数中有一个无效的参数,我猜它是句柄函数,我用谷歌搜索了一种方法找到解决此运行时错误的方法,但我无法做到这一点。

public: static bool ListenOnPort(int port)
{
    int error = WSAStartup(0x0202, &w);
    if (error)
    {
        printf_s("Por alguna razón no se ha podido iniciar WSAStartup");
        WSACleanup();
        return false;
    }
    if (w.wVersion != 0x0202)
    {
        WSACleanup();

        return false;
    }
    SOCKADDR_IN addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    mysocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (mysocket == INVALID_SOCKET)
    {
        printf_s("No se ha podido iniciar el socket 's'");
        Functions::CloseConnection();
        return false;
    }
    listen(mysocket, SOMAXCONN);
    if (!WSAAsyncSelect(mysocket,Hwnd, MY_MESSAGE_NOTIFICATION, (FD_ACCEPT | FD_CONNECT |FD_READ | FD_CLOSE)))
    {
        printf("\nWSAAsyncSelect initialized succesfully\n");
    }
    else
    {
        printf("\nAn error ocurred while executing WSAsyngSelect (%d)[1]\n", WSAGetLastError());
    }
    if (bind(mysocket, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
    {
        printf("We coundnt bind");
        Functions::CloseConnection();
        return false;
    }
    return true;
}

以及 WndProc 函数:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    Hwnd = (HWND)GetModuleHandle(NULL);
    switch (message)
    {
        case MY_MESSAGE_NOTIFICATION:
        {
            switch (lParam)
            {
                case FD_ACCEPT:
                {
                    printf_s("There's a connection incomming\n");
                    accept(wParam, 0, 0);
                    break;
                }
                case FD_CONNECT:
                {
                    printf("A socket has just connected to the host.\n");
                    break;
                }
                case FD_READ:
                {
                    char buf[256];
                    memset(buf, 0, sizeof(buf));
                    recv(mysocket, buf, sizeof(buf)-1, 0);
                    break;
                }
                case FD_CLOSE:
                {
                    printf_s("A connection has just been shutted down.\n");
                    Functions::CloseConnection();
                    break;
                }
            }
        }
        default:return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
    //break;
}

编辑:我的主要功能:

int main(int argc, char *argv[])
{
    //printf_s("Ingresa la dirección IP para conectar.\n");
    if (argc != 0)
    {
        Functions::ListenOnPort(7182);
        while (true)
        {
            if (Conectado == false)
            {
                printf_s("\nConnecting to %s on port 7182\n", (char*)"127.0.0.1");
                Functions::ConnectToHost(7182, (char*)"127.0.0.1");
                cin.get();
            }
            else
            {
                Sleep(120);
            }
        }
    }
    Functions::CloseConnection();
    return 0;
}

最佳答案

这行代码不对:

Hwnd = (HWND)GetModuleHandle(NULL);

模块句柄的类型为HMODULE,与类型为HWND的窗口句柄完全不同。您需要后者。

看起来您没有创建窗口。您需要通过调用 CreateWindow 来完成此操作。您希望通过将 HWND_MESSAGE 传递给 CreateWindowhWndParent 参数来创建仅消息窗口。您必须在调用 WSAAsyncSelect 之前创建窗口,原因很明显,您需要将窗口句柄传递给 WSAAsyncSelect

您还需要运行消息循环才能调度套接字消息。您的程序中似乎也缺少这一点。

这是一个相当复杂的主题。我建议您找到一些异步 Windows 套接字的示例代码并从那里开始。

关于c++ - 如何使 WSAAsyncSelect 在应用程序控制台中启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23552949/

相关文章:

iOS:发送缓冲区中的套接字连接错误

delphi - 我如何确定进程 ID (PID) 是 32 位还是 64 位应用程序?

c# - 设置事件窗口

c++ - 如何获得给定进程的窗口站?

sockets - 使用 ResourceT 清理资源的正确方法是什么?

java - 等待客户端读取消息的套接字服务器

c++ - 一次加载大块 csv 而不是使用 getline 的方法?

c++\编译成功,无法调试 - STATUS_DLL_NOT_FOUND

c++命令行宏预处理器无法替换单词

c++ - 为什么我不能在 `ranges::begin` 上调用 `const filter_view` ?