if (m_Connections[t].socket != INVALID_SOCKET)
{
m_TCPResult = recv(m_Connections[t].socket, m_TCPRecvbuf, m_TCPRecvbuflen, 0);
if (m_TCPResult > 0)
{
printf("[TCPReceive] Bytes (m_TCPResult) received from %d: %d\n", m_Connections[t].socket, m_TCPResult);
// Deserialize the data
Packets::MainPacket receivedData;
memcpy(&receivedData, m_TCPRecvbuf, sizeof(receivedData));
// Check the type and do something with the data
CheckType(m_Connections[t].socket, receivedData);
}
else
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
printf("TCPReceive error: %d\n", WSAGetLastError());
}
}
所以我有这段代码。我需要做一个memcpy()来将来自winsock的传入数据转换为可以被应用程序读取的结构。但是,在CheckType()方法完成后,应用程序崩溃,给我一个访问冲突读取位置错误。我删除了memcpy()方法一次检查然后它工作正常(没有崩溃)。
我不知道问题可能是什么。我一直在谷歌搜索,但没有发现任何有用的东西似乎是我的问题的解决方案
编辑:
更多信息:
// in the header
char m_TCPRecvbuf[DEFAULT_BUFLEN];
// receivedData struct
struct MainPacket
{
char type;
int id;
LoginData loginData;
vector<PlayerData> playerData;
};
答案 0 :(得分:1)
当您执行vector
时,您正在撰写memcpy
。这不是POD你不能通过memcpy
初始化它,而是必须使用它的成员函数来初始化它。
以这种方式思考,vector
将指向它管理的数据,并且size_t
至少指示大小。您不能只通过memcpy
通过网络收到的值来初始化指针。指针可能对发送者有意义,但是当你收到它时,你所拥有的只是一个在服务器上有效的指针,而不是你的应用程序。因此,当您尝试使用vector
时,您将获得未定义的行为,并且可能会崩溃(如果您很幸运)。
此外,由于此sizeof
不适用于您应用于类时的预期方式。例如,如果您的vector
中包含1,000个项目,那么sizeof
将不会反映这一点。 sizeof
告诉您的是类定义中所有成员变量的组合大小(取决于填充)。如果我们的vector
实现只是一个指针和size_t
那么它在32位平台上可能大约为8个字节,而在64位平台上则为16个,无论向量中有多少项。
您需要做的是对数据包中的信息进行编码,以便对其进行解码。例如,不是发送vector
您的数据包应该包含一个字段,指示PlayerData
个实例的数量,然后是每个播放器的数据。