简体   繁体   中英

How to copy Buffer bytes block in Poco C++?

Hi i am trying to write a TCP connection in poco. the client sends a packet with this fields :

packetSize : int date : int ID : int

so the first 4 bytes contains the packet size. in the receive side i have this code :

int packetSize = 0;
char *bufferHeader = new char[4];

// receive 4 bytes that contains packetsize here
socket().receiveBytes(bufferHeader, sizeof(bufferHeader), MSG_WAITALL);

Poco::MemoryInputStream *inStreamHeader = new Poco::MemoryInputStream(bufferHeader, sizeof(bufferHeader));
Poco::BinaryReader *BinaryReaderHeader = new Poco::BinaryReader(*inStreamHeader);

(*BinaryReaderHeader) >> packetSize; // now we have the full packet size

Now I am trying to store all remaining incoming bytes into one array for future binary reading :

int ID = 0;
int date = 0;
int availableBytes = 0;
int readedBytes = 0;
char *body = new char[packetSize - 4];

do
{
    char *bytes = new char[packetSize - 4];

    availableBytes = socket().receiveBytes(bytes, sizeof(bytes), MSG_WAITALL);

    if (availableBytes == 0)
        break;

    memcpy(body + readedBytes, bytes, availableBytes);

    readedBytes += availableBytes;

} while (availableBytes > 0);

Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body, sizeof(body));
Poco::BinaryReader *BinaryReader = new Poco::BinaryReader(*inStream);

(*BinaryReader) >> date;
(*BinaryReader) >> ID;

cout << "date :" << date << endl;
cout << "ID :" << ID << endl;

the problem is the byte block of body is not storing the remaining bytes , it has always only the first 4 bytes (date). so in the out put the date is correct but the ID is not as expected. I tried to Stream it without Block copy and manually receive the each field without loop, it was just fine and had expected data. but when i try to store the incoming bytes into one array and then pass that array to a memorystream to read it, i have only the first block correct and expected!!

I really need to store all incoming bytes into one array and then read whole that array, how should i change my code?

thanks alot

I see two errors in your code. Or, more precisely, an error you do twice. You confuse sizeof of char[] with sizeof of char * ; the first is the number of characters in the array, the second is the size of the pointer: typically 4 or 8 bytes, depending on the memory model.

So, when you write

availableBytes = socket().receiveBytes(bytes, sizeof(bytes), MSG_WAITALL);

you are asking for 4 (I suppose) bytes. This is not serious as you continue to ask other bytes until the message is finished.

The real problem is the following instruction

Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body, sizeof(body));

where you transfer only sizeof(char *) bytes in inStream

You should substitute sizeof(body) and sizeof(bytes) with packetSize - 4 .

Ps: sorry for my bad english

: I've seen another error. :我看到了另一个错误。 In this instruction

 char *bytes = new char[packetSize - 4];

you allocate packetSize - 4 chars. This memory in never deleted and in allocated in the do ... while() cycle.

You can allocate bytes outside of the cycle (togheter with body ).

Proposed solution (caution: non tested)

size_t  toRead  = packetSize - 4U;
size_t  totRead = 0U;
size_t  nowRead;

char * body = new char[toRead];

do 
{
  nowRead += socket().receiveBytes(body+totRead, toRead-totRead,
                MSG_WAITALL);

  if ( 0 == nowRead )
     throw std::runtime_error("shutdown from receiveBytes()");

  totRead += nowRead;

} while ( totRead < toRead );

Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body, 
                                           toRead);

delete[] body;

body = NULL;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM