2013-05-31 4 views
1

Я попытался отправить 5,000 байт char пакета на boost::asio. Но я получил ошибку: buffer overflow. Есть ли способ увеличить раскол автоматически или я должен сделать это вручную?Boost ASIO: переполнение буфера с пакетом 5 kb

Вот код пакета:

char * CPlayerCharacter::getEnviPacket() //len 5824 
{ 
char * buffer = new char[5824]; 
char xf[4]; 
char yf[4]; 
sprintf(xf, "%f", x); 
sprintf(yf, "%f", y); 
for(int i =0;i<5824;i++) 
{ 
    buffer[i] = 0x00; 
} 
buffer[0] = 5824 & 0xff; 
buffer[1] = 5824 >> 8 & 0xff; 
buffer[4] = 4; //minor id 
buffer[6] = 1; //major id 
buffer[8] = 1; 
buffer[12] = id & 0xff; 
buffer[13] = (id>>8) & 0xff; 
buffer[14] = (id>>16) & 0xff; 
buffer[15] = (id>>24) & 0xff; 
buffer[20] = mapid;//map id 
buffer[24] = 18; 
buffer[28] = 0x0a; 
buffer[29] = 0x0f; 
buffer[30] = 0x16; 
for(int i =0;i<4;i++) 
{ 
    buffer[5800+i] = xf[i]; 
    buffer[5804+i] = yf[i]; 
} 
buffer[5808] = 0x0c; 
buffer[5813] = 0x9d; 
buffer[5814] = 0x0f; 
buffer[5815] = 0xbf; 
buffer[5822] = 0x60; 
buffer[5823] = 0x2a; 
return buffer; 
} 

Вот код обработчика:

void CConnection::handle_enter_world(int packetlen) 
{ 
Decryptor dec; 
char buffer[packetlen]; 
boost::asio::async_read(socket_, 
     boost::asio::buffer(buffer, packetlen), 
     boost::bind(
      &CConnection::nothing, shared_from_this())); 
char * decrypted = decrypted = dec.decrypt((char*)&buffer, packetlen); 
asynchronousSend(pl.characters[(int)decrypted[0]].getEnviPacket(), 5824); 
} 

А вот функция asynchronousSend:

void CConnection::asynchronousSend(char * data, int len) 
{ 
    boost::asio::async_write(socket_, boost::asio::buffer(data, len), boost::bind(&CConnection::handle_write, shared_from_this())); 
    delete [] data; 
} 

Спасибо.

+0

Это зависит от кода, который вы использовали, но вы не разместили _that_. – Chad

+0

Хорошо, я добавил код. –

ответ

0

Вы пытаетесь использовать асинхронные вызовы async_read и async_write синхронно. Это не будет работать.

void CConnection::handle_enter_world(int packetlen) 
{ 
Decryptor dec; 
char buffer[packetlen]; 
boost::asio::async_read(socket_, 
     boost::asio::buffer(buffer, packetlen), 
     boost::bind(
      &CConnection::nothing, shared_from_this())); 

// RIGHT NOW -- nothing has been read yet. 
// ... 
} 

Когда чтение завершено, вы будете уведомлены с помощью функции обратного вызова вы предоставили (CConnection::nothing). Именно здесь должно быть ваше «дешифрование».

Другой вопрос:

void CConnection::asynchronousSend(char * data, int len) 
{ 
    boost::asio::async_write(socket_, boost::asio::buffer(data, len), boost::bind(&CConnection::handle_write, shared_from_this())); 
    // RIGHT NOW -- nothing has been written yet 
    delete [] data; 
} 

Аналогичный вопрос здесь. Когда запись будет завершена, вы будете уведомлены через предоставленную вами функцию обратного вызова (CConnection::handle_write). Прежде чем позвонить delete[] на data, данные, которые вы отправляете, будут повреждены. Вам необходимо удалить эту память в функции обратного вызова (или, еще лучше, сделать эту память также совместно используемым указателем).

Если вы хотите, чтобы код выполнялся синхронно, вы могли вместо этого использовать синхронные вызовы boost::asio::write и boost::asio::read (или read_until).

+0

Спасибо за ответ, но есть ли идея отправить этот пакет 5kb без его ручного управления? –

+0

Вам не нужно разделить его вообще, вам нужно использовать функции, которые вы вызываете соответствующим образом. – Chad

+0

Я изменил его, чтобы удалить обратный вызов handle_async_write, но такая же проблема все еще возникает. Ошибка: *** обнаружено переполнение буфера ***: ./game завершено Система: ubuntu –

Смежные вопросы