微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

BakkesMod winsock2接收崩溃

如何解决BakkesMod winsock2接收崩溃

使用winsock2.h && Ws2tcpip.h && bakkesmod SDK的C ++ BakkesMod插件(仅需要x64 Release构建)

问题:recv()崩溃。 Try-Catch不会停止它,线程不会停止它,所有检查都表明它应该可以正常工作。发送工作正常,虽然我可能可以创建仅发送ping,但是我想使用其他功能,这些功能需要从服务器接收小的请求。

Note的初始化变量:

// Socket.private
int sock;
std::thread* reader;
// Socket.public
std::function<void(void)> onConnect;
std::function<void(void)> ondisconnect;
std::function<void(std::string)> onMessageReceived;
std::function<void(ErrorType,std::string)> onError;

// Relevant Function(s)
int Socket::Connect(int tries) {
    if (tries <= 0)
        return -1;

    if (ConnectionState == 1)
        disconnect();
    ConnectionState = 0;
    
    if (onError != NULL)
        onError(ErrorType::DEBUG,"discord: Connecting...");
    struct sockaddr_in serv_addr;
    if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        if (onError != NULL)
            onError(ErrorType::CREATE_Failed,"discord: Could not Create Socket");

        if (ondisconnect != NULL)
            ondisconnect();

        return Connect(tries - 1);
    }
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(this->Port);

    // Convert IPv4 and IPv6 addresses from text to binary form 
    if (inet_pton(AF_INET,this->Address.c_str(),&serv_addr.sin_addr) <= 0)
    {
        if (onError != NULL)
            onError(ErrorType::BIND_Failed,"discord: Could not Bind Socket");

        if (ondisconnect != NULL)
            ondisconnect();

        return Connect(tries - 1);
    }
    if (connect(sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    {
        if (onError != NULL)
            onError(ErrorType::CONNECT_Failed,"discord: Could not Connect");

        if (ondisconnect != NULL)
            ondisconnect();

        return Connect(tries - 1);;
    }

    ConnectionState = 1;
    
    if (onError != NULL)
        onError(ErrorType::DEBUG,"discord: Authenticating...");
    Send("AUTH " + this->AuthCode,1);

    if (onConnect != NULL)
        onConnect();

    std::thread thread_obj([this] { this->Read(); });
    this->reader = &thread_obj;

    return 1;
}

阅读通话:

#pragma warning( disable : 4700 )
void Socket::Read() {
    if (onError != NULL)
        onError(ErrorType::DEBUG,"discord: Receive Thread Started");
    int len = 0;
    // Tried {0} to solve warning 4700,also left uninitialized with same result
    char* msg = { 0 };
    int bytesreceived = 0;
    while (ConnectionState == 1) {
        do {
            char buffer[MAX_BUFFER];
            int buflen = MAX_BUFFER;
            if (onError != NULL)
                onError(ErrorType::DEBUG,"discord: Receiving...");
            try {
                // *CRASH LINE*
                len = recv(this->sock,buffer,buflen,0);
            }
            catch (int e) {
                if (onError != NULL)
                    onError(ErrorType::DEBUG,"discord: Receive Error (" + std::to_string(e) + ")");
            }

            if (onError != NULL)
                onError(ErrorType::DEBUG,"discord: Received " + std::to_string(len) + " bytes");
            if (len > 0) {
                // Concatenate Buffer
            }
            if (onError != NULL)
                onError(ErrorType::DEBUG,"discord: Buffered " + std::to_string(bytesreceived) + " bytes");
            // Parse for Command(s)
    }
    if (bytesreceived > 0) {
        if (onError != NULL)
            onError(ErrorType::NOT_CONNECTED,"discord: Receive Closed with Data");
    }
    if (onError != NULL)
        onError(ErrorType::DEBUG,"discord: Receive Thread Ended");
}

调试输出

[17:09:46] [bakkesmod] [class plg::Foxsleaderboard] discord: AutoConnecting
[17:09:46] [bakkesmod] [class plg::Foxsleaderboard] discord: Connecting...
[17:09:46] [bakkesmod] [class plg::Foxsleaderboard] discord: Authenticating...
[17:09:46] [bakkesmod] [class plg::Foxsleaderboard] discord Connected
[17:09:46] [bakkesmod] [class plg::Foxsleaderboard] discord: Receive Thread Started
[17:09:46] [bakkesmod] [class plg::Foxsleaderboard] discord: Receiving...

解决方法

这与date --date "2020-10-03 +2 second 17:49:23" "+%Y-%m-%dT%H:%M:%S" date --date "+2 second 2020-10-03T17:49:23" "+%Y-%m-%dT%H:%M:%S" 无关。

recv

这将构造一个std::thread thread_obj([this] { this->Read(); }); this->reader = &thread_obj; return 1; 对象,创建一个新的执行线程。

此后,此功能立即std::thread s。

从函数返回将破坏自动范围内的所有对象。包括此return对象。就像其他任何局部变量一样被破坏。

销毁具有未分离的执行线程的std::thread会导致std::thread被调用,从而终止整个程序。

另外,请注意,函数返回后,std::terminate指针也是悬空指针,指向已损坏的对象。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。