2015-08-09 5 views
2

Я написал небольшую программу с библиотекой boost asio для передачи файлов через TCP с сервера одному или нескольким клиентам.Сколько данных для отправки через TCP/IP сразу

Во время тестирования выяснилось, что передача происходит очень медленно, около 10KiB/s. Алгоритм Нагле уже отключен. Если я передам тот же файл через FileZilla с того же сервера на тот же клиент, я получаю около 280KiB/s, поэтому очевидно, что что-то было очень не так.

Мой подход до сих пор заключался в том, чтобы фрагментировать каждый файл в меньшие пакеты 1024 байта, отправлять клиенту один фрагмент (каждый фрагмент = 1 async_write-call) и ждать ответа клиента. Мне нужно фрагментировать данные, чтобы клиент мог отслеживать ход загрузки и скорость. Оглядываясь назад, я предполагаю, что это было довольно наивно, потому что сервер должен ждать ответа клиента после каждого фрагмента. Для того, чтобы проверить, было ли это узкое место, я увеличил размер фрагмента в два раза, что дает мне следующие результаты:

a) Fragment Size: 1024bytes 
Transfer Speed: ~10KiB/s 
b) Fragment Size: 8192bytes 
Transfer Speed: ~80KiB/s 
c) Fragment Size: 20000bytes 
Transfer Speed: ~195KiB/s 

Результаты говорят сами за себя, но я не уверен, что теперь делать.

Я не слишком хорошо знаком с тем, как передача данных фактически обрабатывается внутренне, но если я не ошибаюсь, все мои данные в основном добавляются в поток? Если это так, мне нужно беспокоиться о том, сколько данных я пишу в этот поток сразу? Имеет ли значение вообще то, пользуюсь ли я несколькими вызовами записи с небольшими фрагментами, а не одним вызовом записи с большим фрагментом? Существуют ли какие-либо рекомендации для этого?

+0

Избавьтесь от подтверждения и поднимите размер буфера, по крайней мере, на 32 КБ. – EJP

ответ

1

Просто передайте данные клиенту без искусственной пакетизации. Повторное наглывание, это не сценарий, который требует его отключения. Это приведет к небольшой неэффективности, чтобы она была отключена.

Типичные размеры буфера записи будут 4 КБ и выше.

Клиент может передавать вызовы чтения в сеть один за другим. После каждого успешного чтения у клиента будет новая оценка для текущего прогресса, которая достаточно точна. Как правило, для каждого принятого сетевого пакета будет один последующий вызов для чтения. Если входящая скорость очень высока, то несколько пакетов, как правило, объединяются в одно чтение. Это не проблема.

Если это так, мне нужно беспокоиться о том, сколько данных я пишу в этот поток сразу?

Нет. Просто держите вызов записи незабываемым в любое время.