C ++ Как правильно получить файл в Winsock? - PullRequest
2 голосов
/ 02 июля 2019

Я работаю над программой CHAT на C ++. И застрял на проблеме отправки / получения файла. Моя серверная сторона - это Python, который работает на фоне приложения Flask, принимающего TCP-соединения и пересылающего входящие / исходящие данные клиентам чата. Это не проблема и прекрасно работает. Моя проблема в получении клиента. Я добавил эту функцию отправки и получения файла. Пока send выходит нормально без ошибок (проверено и работает). Получение на стороне клиента дало мне головную боль.

Я использую следующее для получения файла, является ли он двоичным или текстовым.

// filebuf is defined as
// char filebuf[BUFFER];
// BUFFER is 1024.
void CHAT::recvFile()
{
 int fsize;
 std::ofstream recvfile(filename, std::ios::app, std::ios::binary);
 while ((fsize = recv(sockfd, filebuf, sizeof(filebuf), 0)) > 0)
 {
     recvfile.write(filebuf, sizeof(filebuf));
 }
 recvfile.close();
 respond("Received file.\n");
}

Это работает, но данные не записаны в файл полностью. Например; Если я отправлю файл размером 144 КБ, он будет сохранен на другой стороне как 142 КБ. И программа просто останавливается на этом.

Последний вопрос; Как получить большой / маленький файл в C ++?

РЕДАКТИРОВАТЬ: После ответа @Algirdas Preidžius, я перепроверил его. Вот несколько скриншотов файла до и после отправки.

Это до отправки.

https://www.upload.ee/image/10164543/ook.PNG

Это после отправки. https://www.upload.ee/image/10164544/wsa.PNG

1 Ответ

0 голосов
/ 03 июля 2019

Есть 3 способа справиться с этой ситуацией.

  • Разделители сообщений / разделитель строк
  • Вставка размера сообщения перед сообщением
  • Используйте неблокирующий ввод / вывод в сочетании с select

Вот краткий пример синтаксического анализа входящего сообщения в поисках ограничителя строки. Например:

int fsize;
std::string filebuf( '0', 1024 );

while ( ( fsize = recv( sockfd, filebuf.data( ), filebuf.size( ), 0 ) ) > 0 )
{
     if( std::size_t index{ filebuf.find( "#end", 0 ) }; 
          index != std::string::npos )
     {
         // The line terminator was found so don't call the
         // the receive function again as there should be nothing
         // remaining in the stream to read.
     }
     /*Write the data to your file.*/
     filebuf.clear( );
}
respond("Received file.\n");

Обратите внимание, что это быстрый непроверенный пример, показывающий, как можно проанализировать входящее сообщение.

...