0

编辑代码当我最初发布时,我对下面的代码感到非常糟糕。最后我遇到的问题是我得到了我已经传递给函数的大小值的“sizeof”。因此我总是写 4bytes 而不是实际大小。基本上我做了这样的事情:

size = sizeof(valueIWantToSend);
finalSizeToWrite = sizeof(size); //derpderpderp

我已经修复了下面的示例代码。


在创建要发送的网络数据包时,尝试做一些更复杂的事情来尝试清理我的代码。

这个想法是有一个功能,如:

AppendPacket(dataToBeSent, sizeOfData)

我坚持的部分是让 dataToBeSent 通过此功能正确复制。

以前我会有几行凌乱的“memcopy”,它们会将数据填充到指定位置的缓冲区中。这种方式有效,经过尝试和测试。尽管有下面的示例,但它的杂乱无章并且需要维护。

memcpy((char*)GetBufferPositionIndex(), (char*)&dataToBeSent, sizeof(sizeof(dataToBeSent)));
StepBufferPositionForward(sizeof(dataToBeSent));

所以,是的,这是我目前在整个游戏代码的各个地方使用的更易于理解的版本,用于打包我需要发送给多人游戏客户端的数据。

我不想在所有地方复制这些行,而是使用我的 AppendPacket() 函数。最初它看起来与此类似:

//How I tend to use the function in my code
double playerVelocity = 22.34;
AppendPacket( &playerVelocity, sizeof(playerVelocity) );


//Definition
AppendPacket( void* dataToBeSent, size_t sizeOfData )
{
     memcpy( (char*)GetBufferPositionIndex(), dataToBeSent, sizeof(sizeOfData) );
     StepBufferPositionForward( sizeof(sizeOfData) );
}

从我通过调试可以看出,我实际上是在发送数据的地址,而不是它自己的实际数据。

我已经通过函数和“dataToBeSent”部分尝试了指针符号和地址符号的各种组合,但我没有运气:(

以上需要处理各种数据格式,例如结构、字符数组、单字节、双精度、整数、浮点数等。

关于我应该如何做的任何想法?整个晚上和早上都在绞尽脑汁:(


对于好奇的:GetBufferPositionIndex()本质上返回缓冲区中下一个开始写入的位置。

unsigned char packetToBeSentBuffer[PACKET_SIZE];
unsigned char* bufferIndexCurrent;
unsigned char* bufferIndexStartPosition;

unsigned char* GetBufferPositionIndex();
void StepBufferPositionForward(int sizeOfVar);

unsigned char* GetBufferPositionIndex()
{
     return bufferIndexCurrent;
}

void PlayerObj::StepBufferPositionForward(int sizeOfVar)
{
     bufferIndexCurrent += sizeOfVar;
     if (messageToSendIndex > (( bufferIndexStartPosition + PACKET_SIZE) - 200))
     {
           cout << "WARNING: Packet for this tick has less than 200 bytes left until full\n";
     }
}
4

1 回答 1

2

在不知道代码最终如何进入套接字读取/写入以及缓冲区如何工作的情况下,我不完全确定现在确切的问题出在哪里,但这里有一个建议,以进一步简化您的代码。

该代码仍然容易出错,因为您需要确保您传递的数据大小是正确的。新功能的一个错误的复制粘贴错误的大小,你又遇到了错误。对于这些情况,我总是建议一个简单的模板:

template <typename T>
AppendPacket( T& data )
{
    std::size_t size = sizeof(T);
    memcpy( some_destination, &data, size );
    StepBufferPositionForward( size );
}

struct whatever a;
AppendPacket(a);

double b;
AppendPacket(b);

int c[5] = {1, 2, 3, 4, 5};
AppendPacket(c);

这样,编译器每次都会为您计算出数据的大小。

关于缓冲区,固定大小会出现问题,因为目前 AppendPacket 不处理超过数据包大小的情况。有两种解决方案:

  • 获取要写入缓冲区的位置时抛出异常
  • 有一个可动态调整大小的缓冲区

我将举例说明如何处理第二种情况:

class Client
{
    std::vector<char> nextPacket;

public:

    template <typename T>
    AppendToPacket( T& data )
    {
        // figure out the size
        std::size_t size = sizeof(T);

        // expand vector to accomodate more space
        nextPacket.reserve(size);

        // append the data to the vector
        std::copy_n( static_cast<char const*>(&data),
                     size,
                     std::back_inserter(nextPacket) );
    }

}
于 2012-12-27T03:05:45.187 回答