C # сокеты, получать большие файлы - PullRequest
0 голосов
/ 10 февраля 2012

Я сейчас работаю с асинхронными сокетами. У меня есть функция обратного вызова «onDataReceived», которая запускается всякий раз, когда я получаю какие-либо данные.

Сначала я получал один символ за раз, поэтому я изменил буфер данных socketPacket на большой массив. Теперь, когда я получаю данные, я получаю их все сразу, но когда я пытаюсь отправить файл большего размера, он не работает, когда он превышает размер массива.

Мой вопрос такой. У меня многопоточный сокет-сервер. Как я могу определить, когда все данные получены? например, мне нужно отправить изображение, я кодирую изображение в base64 и создаю команду "BASE64IMAGE", а затем сервер читает строку, пока она не достигнет END_OF_DATA? Есть ли лучший способ сделать это? спасибо!

Ответы [ 2 ]

6 голосов
/ 10 февраля 2012

Мой вопрос такой.У меня многопоточный сокет-сервер.Как определить, когда получены все данные?

Существует три стандартных варианта отправки «сообщения» (будь то изображение или что-то еще - целый блок данных, который может быть большим):

  • Одно сообщение для каждого соединения: вы можете обнаружить конец сообщения по тому, как другой конец закрывает соединение
  • Какой-то маркер «конечного сообщения»: когда вы читаете данные,Вы проверяете наличие специального маркера, который указывает на конец сообщения.Если маркер может появиться естественным образом, вам нужно его избежать - и не показывать при чтении
  • Заголовок, указывающий размер сообщения перед отправкой фактических данных - просто прочитайте столько байтов

Лично мне нравится последний вариант - он делает чтение данных и уверенность в том, что у вас все это намного проще, чем в первых двух вариантах.Вы можете выделить необходимый объем памяти для получения данных перед началом и т. Д. Однако, это не очень хорошо, если вы не знаете размер сообщения перед началом.Вы можете изменить схему, имея несколько «чанков» для одного сообщения, где вы отправляете размер чанка, а затем данные, а размер чанка 0 указывает конец данных.

Обратите внимание, что если вы 'если вы пересылаете данные только через сокет, и вам не нужен 7-битный чистый ASCII, я не сначала преобразую в Base-64.Просто передайте его как двоичные данные - ваш код будет проще и эффективнее как по времени, так и по полосе пропускания.

1 голос
/ 10 февраля 2012

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

Например, вы кодируете свой файл и определяете, что кодированный размер составляет 800 байтов.Вы отправляете число 800 (скажем, в четырех байтах), затем файл.

Принимающая сторона читает четыре байта, получает число 800, а затем знает, что нужно прочитать еще 800 байтов, чтобы получить весь файл.

Это называется префиксом длины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...