Most of the time, one got to look at the actual problem.
Parsing a packet protocol may or may not be easy, depending on the specification, but you can usually do better than throwing it all in a string...
If you don't know about them, look up Google Protocol Buffer, they can't be used as is, but the idea is there.
class UdpPacket
{
public:
  UdpPacket(const char str[], size_t length);
  uint16_t sourcePort() const { return mSourcePort; }
  unit16_t destinationPort() const { return mDestinationPort; }
  // ... The 3 other getters
private:
  uint16_t mSourcePort;
  uint16_t mDestinationPort;
  uint16_t mLength;
  uint16_t mCheckSum;
  std::string mData;
}; // class UdpPacket
UdpPacket::UdpPacket(const char str[], size_t length):
  mSourcePort(0), mDestinationPort(0), mLength(0), mCheckSum(0),
  mData()
{
  if (length < 8) throw IncompleteHeader(str, length);
  memcpy(mSourcePort, str, 2);
  memcpy(mDestinationPort, str, 2);
  memcpy(mLength, str, 2);
  memcpy(mCheckSum, str, 2);
  mData = std::string(str+8, length-8);
} // UdpPacket::UdpPacket
Net advantage ? You now have structured data. Of course there might be some endianness issue going on with the memcpy... you'll have to check for it.
Now, I don't know what your mData is supposed to be, but of course it would be better if it was structured too.
Using a simple int to store what does not look like an int at all, really is a bad idea I think... unless it was an int to begin with of course.