【问题标题】:Running into a heap corruption with WinSock2 application使用 WinSock2 应用程序遇到堆损坏
【发布时间】:2013-08-06 20:40:16
【问题描述】:

我觉得这是一个愚蠢的错误,但我正在制作一个回显服务器来识别数据包,并输出数据,然后重新发送回去。它适用于某些数据包,但我试图回应的一个数据包正在中断并说有一个堆被损坏。

Vector 类,暂时只用作容器:

class vec2
{
public:
     vec2(){};
     float x, y;
};

PlayerData 结构:

struct PlayerData
{
    vec2 pos;
    int health;
    float rotation;
    char moveflags;
    short playerID;
};

我正在尝试发送的数据包:

struct ServerPacket_SyncGame //5
{
     short packetID;
     PlayerData data[8];
};

下一部分很混乱,但我会对其进行评论以使其有意义。

ServerPacket_SyncGame* SP_SG = new ServerPacket_SyncGame; //creates packet pointer
for(int i = 0; i < 8; i++) //assigns the eight playerdata structs in the packet array
{
    SP_SG->data[i].playerID = i;
    SP_SG->data[i].health = rand() % 30;
    SP_SG->data[i].moveflags = 'D';
    SP_SG->data[i].pos.x = rand() % 1000;
    SP_SG->data[i].pos.y = rand() % 1000;
    SP_SG->data[i].rotation = rand() % 360;
}
SP_SG->packetID = 5; //assigns the packet id

cout << "\n\nSent data: \n"; ////Outputting the data to be sent
for(int i = 0; i < 8; i++)
    cout << "\nPlayer ID: " << SP_SG->data[i].playerID << "\nPosition: (" 
         << SP_SG->data[i].pos.x << ", " << SP_SG->data[i].pos.y 
         << ")\nHealth: " << SP_SG->data[i].health << "\nRotation: " 
         <<SP_SG->data[i].rotation << "\nMove Flags: "
         << SP_SG->data[i].moveflags << endl;

void* SP_SG_DAT = (void*)SP_SG; //casting the packet into a void*

char* SP_SG_BUFF = (char*)SP_SG_DAT; //casting from a void* to a char*

send(Socket, SP_SG_BUFF, sizeof(ServerPacket_SyncGame), 0); //sends the char*

char* SP_SG_RCVBUFF = new char; //new buffer for recv

recv(Socket, SP_SG_RCVBUFF, sizeof(ServerPacket_SyncGame), 0); //recv new buffer

void* SP_SG_RCVDAT = (void*) SP_SG_RCVBUFF; //casts char* to void* again

ServerPacket_SyncGame* RCVSP_SG = (ServerPacket_SyncGame*) SP_SG_RCVDAT;
//casts from void* to packet*

cout << "\n\nRecieved Data:\n\n";  //outputs converted received information
for(int i = 0; i < 8; i++)
    cout << "\nPlayer ID: " << SP_SG->data[i].playerID << "\nPosition: (" 
         << SP_SG->data[i].pos.x << ", " << SP_SG->data[i].pos.y 
         << ")\nHealth: " << SP_SG->data[i].health << "\nRotation: " 
         <<SP_SG->data[i].rotation << "\nMove Flags: "
         << SP_SG->data[i].moveflags << endl;

我在其他数据包中使用过这个方法,效果很好,服务器端是这样回显的:

for(;;)
     {
          char* buffer = new char;
          char* temp = new char;
          int size = recv(Socket, buffer, sizeof(ServerPacket_SyncGame), 0);
          memcpy(temp, buffer, size);
          send(Socket, (char*)InterpretInfo((void*)temp), size, 0);
     };

InterpretInfo 接受您从收到的 char* 中抛出的 void*,它的处理方式如下:

void* InterpretInfo(void* data)
{

     short* tempsht = static_cast<short*>(data);
     cout << "\n\nRecieved packet ID: " << *tempsht;

     switch(*tempsht)
     {

这个特定数据包的 ID 是 5,就是这样:

case 5:
         //ServerPacket_SyncGame
         {
           cout << " which is ServerPacket_SyncGame\n";
           ServerPacket_SyncGame* decoded = (ServerPacket_SyncGame*)data;
           for(int i = 0; i < 8; i++)
           {
            cout << "Player ID: " << decoded->data[i].playerID ;
            cout << "\nPosition: (" << decoded->data[i].pos.x << ", " 
                             << decoded->data[i].pos.y << ")\n";
            cout << "Health: " << decoded->data[i].health 
                             << "\nRotation: " << decoded->data[i].rotation 
                 << "\nMove Flags: " << decoded->data[i].moveflags << endl;
           }
            return(void*)decoded;
    }

它只对这个数据包执行此操作,当我尝试从数据包中访问任何内容时,它会中断并说堆已损坏,尽管在调试模式下我可以清楚地读取数据包中的所有信息。

我需要至少 10 个代表才能发布一张图片,所以这里有一个链接,指向我在运行代码中所说的内容: http://i.imgur.com/Dbyi0c3.png

非常感谢您提供的任何帮助或见解来帮助我完成这项工作,我还是 C++ 的新手并且喜欢学习。

【问题讨论】:

    标签: heap-memory winsock heap-corruption


    【解决方案1】:

    您只为recv() 缓冲区分配了1 个字节,但您正试图将sizeof(ServerPacket_SyncGame) 的字节数读入其中。你需要改变这个:

    char* SP_SG_RCVBUFF = new char; //new buffer for recv
    

    到这里:

    char* SP_SG_RCVBUFF = new char[sizeof(ServerPacket_SyncGame)];
    

    与您的 for 循环相同:

    for(;;)
    {
        //char* buffer = new char;
        char* buffer = new char[sizeof(ServerPacket_SyncGame)];
        //char* temp = new char;
        char* temp = new char[sizeof(ServerPacket_SyncGame)];
        ...
     };
    

    我建议你清理你的代码:

    ServerPacket_SyncGame* SP_SG = new ServerPacket_SyncGame; //creates packet pointer
    for(int i = 0; i < 8; i++) //assigns the eight playerdata structs in the packet array
    {
        SP_SG->data[i].playerID = i;
        SP_SG->data[i].health = rand() % 30;
        SP_SG->data[i].moveflags = 'D';
        SP_SG->data[i].pos.x = rand() % 1000;
        SP_SG->data[i].pos.y = rand() % 1000;
        SP_SG->data[i].rotation = rand() % 360;
    }
    SP_SG->packetID = 5; //assigns the packet id
    ...
    // don't forget to do error handling on this, and pay attention to the
    // return value so you know if you actually sent the entire struct or not...
    send(Socket, (char*)SP_SG, sizeof(ServerPacket_SyncGame), 0);
    delete SP_SG;
    
    SP_SG = new ServerPacket_SyncGame;
    
    // don't forget to do error handling on this, and pay attention to the
    // return value so you know if you actually received the entire struct or not...
    recv(Socket, (char*)SP_SG, sizeof(ServerPacket_SyncGame), 0); //recv new buffer
    ...
    delete SP_SG;
    

    ServerPacket_SyncGame buffer;
    for(;;)
    {
        // don't forget to do error handling on this, and pay attention to the
        // return value so you know if you actually received the entire struct or not...
        int size = recv(Socket, &buffer, sizeof(ServerPacket_SyncGame), 0);
        if (size > 0)
        {
            // don't forget to do error handling on this, and pay attention to the
            // return value so you know if you actually sent the entire struct or not...
            send(Socket, (char*)InterpretInfo(&buffer), size, 0);
        }
     };
    

    【讨论】:

    • 非常感谢,现在可以使用了。也感谢您对清理我的代码的建议!我真的需要它们。
    猜你喜欢
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多