请注意,由于 MinGW 中缺少线程类支持,我使用的是 boost async。
所以,我想每 5 秒发送一个数据包,并决定为此目的使用 boost::async
(std::async
)。
这是我用来发送数据包的函数(这实际上是复制到缓冲区并在主应用程序循环中发送 - nvm - 它在异步方法之外工作正常!)
m_sendBuf = new char[1024]; // allocate buffer
[..]
bool CNetwork::Send(const void* sourceBuffer, size_t size) {
size_t bufDif = m_sendBufSize - m_sendInBufPos;
if (size > bufDif) {
return false;
}
memcpy(m_sendBuf + m_sendInBufPos, sourceBuffer, size);
m_sendInBufPos += size;
return true;
}
发包代码:
struct TestPacket {
unsigned char type;
int code;
};
void SendPacket() {
TestPacket myPacket{};
myPacket.type = 10;
myPacket.code = 1234;
Send(&TestPacket, sizeof(myPacket));
}
异步代码:
void StartPacketSending() {
SendPacket();
std::this_thread::sleep_for(std::chrono::seconds{5});
StartPacketSending(); // Recursive endless call
}
boost::async(boost::launch::async, &StartPacketSending);
好的。所以问题是,当我从异步方法调用 SendPacket()
时,服务器端接收到的数据包格式不正确,并且数据与指定的数据不同。在异步调用之外调用时不会发生这种情况。
这是怎么回事?我没主意了。
最佳答案
我想我的脑子里全是你在这里做的事。您正在将所有未发送的内容加载到一个线程中的缓冲区,然后在另一个线程中将其刷新。即使数据包没有重叠(假设它们消耗得足够快),您仍然要同步所有共享数据。
m_sendBuf
、m_sendInPos
和 m_sendBufSize
都是从主线程读取的,可能是在 memcpy 或您的缓冲区大小逻辑正在运行时。我怀疑您必须使用适当的队列才能让您的程序从长远来看按预期工作,但请尝试使用互斥锁保护这些变量。
此外,正如其他评论者指出的那样,C++ 不支持无限递归,但这可能不会导致您的格式错误的数据包。
关于C++ 奇怪的异步行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146994/