用WinSock2进行开发,CreateThread()函数出错

我开始开发我的工具,它在TCP级别与net一起工作,并且遇到以下问题:

  • 为Winsock的accept()函数创建线程
  • 我已经搜索了一下,找到了有关创建新线程的参考信息和everey:

  • 它必须具有前缀中的DWORD WINAPI(无符号长__stdcall)
  • 它必须接受LPVOID参数
  • 而这样的函数将作为LPTHREAD_START_ROUTINE结构的CreateThread()函数中的第三个参数使用。

    但编译后我得到了下一个错误:

    (131):错误C2664:'CreateThread':无法将参数3从'DWORD(__stdcall Net :: *)(LPVOID)'转换为'LPTHREAD_START_ROUTINE'

    这是我的代码:

    #include <iostream>
    #include <Windows.h>
    
    #pragma comment(lib, "Ws2_32.lib")
    
    typedef struct Header
    {
    friend struct Net;
    
    private:
        WORD wsa_version;
        WSAData wsa_data;
    
        SOCKET sock;
        SOCKADDR_IN service;
    
        char *ip;
        unsigned short port;
    
    public:
        Header(void)
        {
            wsa_version = 0x202;
    
            ip = "0x7f.0.0.1";
            port = 0x51;
    
            service.sin_family = AF_INET;
            service.sin_addr.s_addr = inet_addr(ip);
            service.sin_port = htons(port);
        }
    
    } Header;
    
    typedef struct Net
    {
    private:
        int result;
    
        void WSAInit(WSAData *data, WORD *wsa_version)
        {
            result = WSAStartup(*wsa_version, &(*data));
    
            if(result != NO_ERROR)
            {
                std::cout << "WSAStartup() failed with the error: " << result << std::endl;
            }
            else
            {
                std::cout << (*data).szDescription << " " << (*data).szSystemStatus << std::endl;
            }
        }
    
        void SocketInit(SOCKET *my_socket)
        {
            (*my_socket) = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
            if((*my_socket) == INVALID_SOCKET)
            {
                std::cout << "Socket initialization failed with the error: " << WSAGetLastError() << std::endl;
                WSACleanup();
            }
            else
            {
                std::cout << "Socket initialization successful!" << std::endl;
            }
        }
    
        void SocketBind(SOCKET *my_socket, SOCKADDR_IN *service)
        {
            result = bind((*my_socket), (SOCKADDR*)&(*service), sizeof(*service));
    
            if(result == SOCKET_ERROR)
            {
                std::cout << "Socket binding failed with the error: " << WSAGetLastError() << std::endl;
                closesocket((*my_socket));
                WSACleanup();
            }
            else
            {
                std::cout << "Socket binding successful!" << std::endl;
            }
    
            result = listen(*my_socket, SOMAXCONN);
    
            if(result == SOCKET_ERROR)
            {
                std::cout << "Socket listening failed with the error: " << WSAGetLastError() << std::endl;
            }
            else
            {
                std::cout << "Listening to the socket..." << std::endl;
            }
        }
    
        void SocketAccept(SOCKET *my_socket)
        {
            SOCKET sock_accept = accept((*my_socket), 0, 0);
    
            if(sock_accept == INVALID_SOCKET)
            {
                std::cout << "Accept failed with the error: " << WSAGetLastError() << std::endl;
                closesocket(*my_socket);
                WSACleanup();
            }
            else
            {
                std::cout << "Client socket connected!" << std::endl;
            }
    
            char data[0x400];
            result = recv(sock_accept, data, sizeof(data), 0);
        }
    
        DWORD WINAPI Threading(LPVOID lpParam)
        {
            SOCKET *my_socket = (SOCKET*)lpParam;
            SocketAccept(my_socket);
        }
    
    public:
        Net(void)
        {
            Header *obj_h = new Header();
    
            WSAInit(&obj_h->wsa_data, &obj_h->wsa_version);
    
            SocketInit(&obj_h->sock);
            SocketBind(&obj_h->sock, &obj_h->service);
    
            HANDLE thrd = CreateThread(NULL, 0, &Net::Threading, &obj_h->sock, 0, NULL);
    
            delete &obj_h;
        }
    } Net;
    
    int main(void)
    {
        Net *obj_net = new Net();
    
        delete &obj_net;
    
        return 0;
    }
    

    你不能使用C ++非静态成员函数。

    使用一个静态的


    Nestal的答案是正确的 - CreateThread需要一个函数,而不是一个方法。 这就是说,这个样本还有很多其他的错误,我不知道是否只是把它放在那里是负责任的事情。

    首先,编码风格很奇怪:样本名义上是用C ++编写的,但实际上看起来像一个C程序。 如果你打算从C切换到C ++,那么请注意,使用这样的“朋友”是一个强烈的暗示,你是“做错了”。

    直接向朋友类的属性直接传递引用的奇怪样式用于隐藏实际的代码问题:即使构建它的过程会失败很多,因为存在许多竞争条件:套接字作为引用传递给线程: &obj_h->sock Threading仍在运行时, &obj_h->sock将被删除。 即使它没有被删除,它(以及从多个线程引用的任何变量)也应该被限定为volatile以确保编译器不会优化实际持久化变量到内存中。

    即使您将线程过程设置为'静态',安全地传递参数,排除竞争条件,并正确地挥发性限定任何共享变量,您也需要添加线程同步来防止访问共享变量。 再次 - 提供的代码样式直接将参考值传递给值,使得很难知道何时可以从不同的线程读取和写入变量 - 使得难以一致地实现同步策略。

    祝你好运。

    链接地址: http://www.djcxy.com/p/78925.html

    上一篇: Developing with WinSock2, error with CreateThread() function

    下一篇: can't seem to find std::thread in msvc++ 2010 express