BakkesMod winsock2 recv 崩溃
BakkesMod winsock2 recv Crash
使用 winsock2.h && Ws2tcpip.h && bakkesmod SDK 的 C++ BakkesMod 插件(仅需要 x64 发布版本)
问题:在 recv() 上崩溃。 Try-Catch 不会阻止它,线程不会阻止它,所有检查都表明它应该可以正常工作。发送工作正常,虽然我可以创建一个只发送的 ping,但我想使用其他功能,这些功能需要从服务器接收小请求。
已初始化的注释变量:
// 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...
这与recv
无关。
std::thread thread_obj([this] { this->Read(); });
this->reader = &thread_obj;
return 1;
这构造了一个std::thread
对象,创建了一个新的执行线程。
之后,这个函数立即return
s.
从函数返回会销毁自动范围内的所有对象。包括这个 std::thread
对象。它像任何其他局部变量一样被销毁。
销毁具有 non-detached 执行线程的 std::thread
会导致 std::terminate
被调用,从而终止整个程序。
此外,请注意您的 reader
指针也是一个悬空指针,指向一个已销毁的对象,在函数 returns.
之后
使用 winsock2.h && Ws2tcpip.h && bakkesmod SDK 的 C++ BakkesMod 插件(仅需要 x64 发布版本)
问题:在 recv() 上崩溃。 Try-Catch 不会阻止它,线程不会阻止它,所有检查都表明它应该可以正常工作。发送工作正常,虽然我可以创建一个只发送的 ping,但我想使用其他功能,这些功能需要从服务器接收小请求。
已初始化的注释变量:
// 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...
这与recv
无关。
std::thread thread_obj([this] { this->Read(); });
this->reader = &thread_obj;
return 1;
这构造了一个std::thread
对象,创建了一个新的执行线程。
之后,这个函数立即return
s.
从函数返回会销毁自动范围内的所有对象。包括这个 std::thread
对象。它像任何其他局部变量一样被销毁。
销毁具有 non-detached 执行线程的 std::thread
会导致 std::terminate
被调用,从而终止整个程序。
此外,请注意您的 reader
指针也是一个悬空指针,指向一个已销毁的对象,在函数 returns.