编辑代码我最初发布时,我的代码非常糟糕。我最终遇到的问题是我得到了我已经传递给函数的大小值的“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";
}
}
答案 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) );
}
}