[C++] VS 2008 Нужна помощь с выделением памяти сокетам

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by aladin1, 16 May 2015.

  1. aladin1

    aladin1 Member

    Joined:
    16 Sep 2009
    Messages:
    330
    Likes Received:
    29
    Reputations:
    7
    Помогите разобраться, при работе с сокетом выделяю память таким образом:
    Code:
    char text[128]={};
    и всё бы ничего, но приходящие ответы от pop-сервера иногда содержат в себе немного мусора в конце ответа, либо часть ответов не отображается полностью, выглядит приём ответа таким образом:
    Code:
    recv(pop, text, sizeof(text), 0);
    затем вывожу на экран:
    Code:
    cout<<text<<"\n";
    Если дать больше памяти, например
    Code:
    char text[1024]={};
    то мусора становится меньше, либо он пропадает вовсе, отсюда возникает подозрение, что
    некоторым ответам нехватает выделенной памяти, вопрос: как можно этого избежать, как выделить памяти столько, сколько нужно под конкретный ответ, не хочется перегружать память, может нужно резервировать ячейку размером, например 2048 бит и по мере надобности давать из неё столько, сколько нужно и каким образом?
     
  2. VY_CMa

    VY_CMa Green member

    Joined:
    6 Jan 2012
    Messages:
    917
    Likes Received:
    492
    Reputations:
    724
    Выделяй динамически на куче
     
    _________________________
    aladin1 likes this.
  3. DartPhoenix

    DartPhoenix Elder - Старейшина

    Joined:
    15 Sep 2013
    Messages:
    1,108
    Likes Received:
    8,496
    Reputations:
    25
    В конце не хватает завершающего нуля и он тебе вываливает содержимое памяти сразу следом за text. Принимай на 1 байт меньше чем размер буфера и все должно быть ок.
     
    aladin1 and Семён like this.
  4. Семён

    Семён New Member

    Joined:
    9 May 2015
    Messages:
    10
    Likes Received:
    1
    Reputations:
    0
    При выводе char* в cout'e, выводятся последовательно ячейки памяти по 1 байту до тех пор, пока не встретится символ конца \0
    да, если коротко, то не хватает выделенной памяти.
    А тебе вообще хранить это надо? Или только выводить?
     
    aladin1 likes this.
  5. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    aladin1, почитай доку по сокетам и в частности по recv:
    соответственно, если тебе recv вернуло что-то отличное от ноля и не SOCKET_ERROR, и это значение будет меньше размера выделенного тобой буфера, то выводи то, сколько получил, иначе, если recv вернет значение равное величине выделенного буфера, то, возможно, но не факт, что есть еще данные в сокете и нужно пойти на "второй", "третий" круг и т.д. пока recv не вернет 0 или ошибку чтения.
    Что касаемо размера буфера, то его обычно делают размеру окна, которое в форточках, если память не изменяет, равняется по умолчанию 8192, но многое еще зависит от тебуемых задач
     
    aladin1 likes this.
  6. aladin1

    aladin1 Member

    Joined:
    16 Sep 2009
    Messages:
    330
    Likes Received:
    29
    Reputations:
    7
    А если выделить 8192 и запустить в 1к потоков такое, не накладно будет для ресов разве?
    Да, но в моём случае сервера с самым первым ответом превышающим даже 512 меня уже не интересуют, скорее всего какой-то шлак висящий на pop порту.

    Пока пришёл к выводу, что надо делать как советовал VY_CMa, но не вкурил ещё как это сделать, исходя из размера ответов уже решать что делать с конкретным сервером, пока что размер ответа определяю так:
    Code:
    recv(pop, text, (sizeof(text)-1), 0);
    cout<<strlen(text)<<"\n";
    В файл ещё пишу это разом с выводом, с записью пока проблем нет, пишет тоже самое, что и выводит.
     
  7. DartPhoenix

    DartPhoenix Elder - Старейшина

    Joined:
    15 Sep 2013
    Messages:
    1,108
    Likes Received:
    8,496
    Reputations:
    25
    Только я не могу понять в чем проблема-то заключается ? Если буфер на стеке не радует - malloc в помощь. Если доступен STL - vector<unsigned char>. Задаем его размер и читаем все в нулевой элемент по указателю. Типо &Foo[0]. Главное не ошибиться с размерами :) Если malloc категорически не радует - есть системные списки с готовыми блоками памяти фиксированного размера (можно так же их самому замутить чтобы не кушать ресурсы которые возможно (или скорее всего) кому-то нужнее :) ). Но в общем случае malloc | realloc рулит.
     
    aladin1 and Семён like this.
  8. aladin1

    aladin1 Member

    Joined:
    16 Sep 2009
    Messages:
    330
    Likes Received:
    29
    Reputations:
    7
    Да я и сам пока не понял, проблемы на данный момент вроде нет, но дабы не было их и в будущем решил подстраховаться, в общем нужны были советы, пока что оставил как есть, выделил
    Code:
    char text[256]={};
    если strlen(text) будет больше хотя бы 250 просто буду игнорировать пока такие сервера и писать лог с такими ответами, затем уже разбираться, на данном этапе всех благодарю, мб вернусь ещё к этому посту в будущем, при возникновении проблемы с памятью =)