将不同类型的数据传递给void指针函数以添加到网络数据包(我想?)

时间:2012-12-27 02:53:23

标签: c++ networking void-pointers

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

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";
     }
}

1 个答案:

答案 0 :(得分: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) );
    }

}