Какой алгоритм будет уместен для передачи массива?

Делаю передачу аудио данных от клиента к серверу по TCP. Описывать сервер не буду, на его стороне все хорошо работает.

На клиенте я открываю аудио файл, читаю его в бинарном виде, записываю весь результат выборки в массив и закрываю файл. Длину массива также подсчитываю. Не могу только понять, как правильно за каждую итерацию отправлять порцию в 320 байт массива в TCP до его окончания? подскажите пожалуйста. Вот что в данный момент у меня получилось, комментариями пометил.

if (OpenDialog1->FileName  != "") { // Если файл выбран
int step_size = 320;

AnsiString get_file = OpenDialog1->FileName;
ifstream audio;
audio.open(get_file.c_str(), ios::binary);

if (audio.is_open()) { // Если файл открыт
    audio.seekg(0, audio.end);  // Конец файла
    int len = audio.tellg();  // Определяем размер файла
    ProgressBar1->Position = 0;
    ProgressBar1->Max = len;  // Корректируем прогресс бар
    audio.seekg(0, audio.beg);  // В начало файла

    char *pData = new char[len];
    audio.read(pData, len); // Читаем и записываем pData
    audio.close(); // Закрываем файл

    while (true) {  // true пока для теста

        /* Здесь необходимо отправить pData в таком виде но по 320 байт
        Form1->IdTCPClient1->Socket->WriteLn(pData);
        */

        ProgressBar1->Position += step_size;

        Sleep(40); // Тормозим итерацию на 40мс
    }

} else {  // Если файл не открыт
    Memo1->Lines->Add("Ошибка открытия файла: " + OpenDialog1->FileName);
}

} else {  // Если файл не выбран
    Memo1->Lines->Add("Файл для трансляции не выбран!");
}

Соединение TCP было заранее установлено и активно на момент передачи данных.


Ответы (1 шт):

Автор решения: gbg

Наиболее оптимальный (и транслируемый в учебниках) метод - пытаться записать в сокет сразу весь массив.

-это приведет к сокращению числа системных вызовов

-это даст возможность TCP сделать свою работу (потому что он Trasmision Control Protocol) наиболее оптимальным образом

Сам алгоритм такой:

char* base   = //указатель на начало данных
size_t total = 320;
size_t size  = 0;
while(size<total)
{
     const int res = send(sock, base + size, total - size, ...);
     if(res <=0)
     {
         //обработать ошибку
     }
     size+=res;
}

То что вы хотите сделать - неоптимально, ненадежно, нестабильно и неправильно.

Тем не менее, можно сделать поведение, похожее на Питон - вам нужно каждую порцию ваших данных в 320 байт отправлять вышеописанным алгоритмом.

→ Ссылка