首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BakkesMod winsock2 recv崩溃

BakkesMod winsock2 recv崩溃
EN

Stack Overflow用户
提问于 2020-10-03 21:25:03
回答 1查看 144关注 0票数 0

使用winsock2.h & Ws2tcpip.h && BakkesMod的C++ bakkesmod插件(只需要x64发布版本)

问题: recv()上的崩溃。尝试-捕捉并不能阻止它,线程不会阻止它,所有的检查都表明它应该正常工作。Send工作正常,虽然我可能能够创建一个仅发送的ping,但我想使用的其他特性需要接收来自服务器的小请求。

注的初始化变量:

代码语言:javascript
复制
// 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;
}

阅读呼叫:

代码语言:javascript
复制
#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");
}

调试输出:

代码语言:javascript
复制
[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...
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-03 21:30:34

这与recv无关。

代码语言:javascript
复制
std::thread thread_obj([this] { this->Read(); });
this->reader = &thread_obj;

return 1;

这将构造一个std::thread对象,创建一个新的执行线程。

之后,这个函数立即return

从函数返回会破坏自动作用域中的所有对象。包括这个std::thread对象。它就像其他局部变量一样被摧毁。

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

另外,请注意,在函数返回后,您的reader指针也是一个悬空指针,指向已销毁的对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64189163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档