2009-10-22 2 views
0

Я разрабатываю приложение, которое обрабатывает (обработку видео и т. Д.) И отправляет большие файлы (до десятков гигабайт) по сети. Я отправляю файлы с помощью FTP. Чтобы повысить производительность/потребление памяти приложения, я бы хотел оптимизировать буферы, чтобы я не отправлял слишком большие и фрагментированные пакеты. Проблема в том, что у меня нет большого количества ОЗУ для хранения данных файла во время отправки. В принципе, я читаю достаточно байт с диска, обрабатываю его и сразу отправляю в пункт назначения. В настоящее время я ищу, чтобы реализовать обнаружение пути MTU.Путь MTU Discovery

Я знаком с базовой концепцией, как это сделать. Я хотел бы знать, есть ли какой-либо .NET API в Windows, который отслеживает MTU для адресата?

Я предполагаю, что такой вещи нет, но мой друг сказал мне, что Windows Vista отслеживает.

Я разрабатываю это приложение для Windows XP, но я хотел бы узнать, существует ли такой API отслеживания сети в Windows.

ответ

2

winsock не поддерживает отчет об обнаруженном MTU, хотя другие стеки TCP/IP (например, AIX через опцию сокета IP_GETPMTU). Поскольку winsock не может сообщить об этом, .NET не может предоставить API (который должен быть поверх winsock).

Я рекомендую отправлять данные в куски 64киB. Это максимальный размер IP-пакета и, вероятно, больше MTU, поэтому стек отправит несколько полных сегментов. Последний фрагмент может быть меньше, но тогда система может отложить его отправку (потому что ему все еще нужно получать подтверждения для более ранних данных), поэтому, если вы будете быстро следить за следующей отправкой 64kiB, система снова объединит куски в пакеты с использованием пути mtu.

+0

А орехи, IP_GETPMTU были тем, что я искал. Во всяком случае, я установлю свое приложение на использование кусков 64кВ. Мое приложение немного скупилось на память, потому что на самом деле это вторая версия программного обеспечения. Первая версия была написана 10 лет назад и очень разумна с памятью. Поэтому, естественно, я стараюсь быть таким же осторожным. –

+0

Что вы можете сделать с возвращаемым значением из IP_GETPMTU? Размер блока, который вы используете для записи в сокет, имеет очень мало общего с тем, что выходит за провод. Я рекомендую попытаться записать столько данных, сколько у вас есть, и иметь дело с частичной записью. Когда вы можете писать, напишите больше. Указание магического числа, такого как 64kB, глупо; как это имеет значение? Если это так, что происходит, когда размер окна превышает 64 КБ? Конечно, с окнами у вас также есть возможность просто подготовить все и сделать большую асинхронную запись. – janm

+0

@janm: см. Оригинальный вопрос. OP не может записать «столько данных, сколько у вас есть», поскольку данные не будут одновременно помещаться в память. –

0

Это не то, что вам нужно делать самостоятельно, если вы используете TCP. Кроме того, нет никакого отношения к размеру ваших буферов отправки. В пути может быть несколько пакетов (вплоть до размера окна TCP), но они больше не будут находиться в буфере, который вы поддерживаете.

+0

Я должен был добавить дополнительную информацию. Я использую FTP. Моя проблема в том, что у меня нет большой памяти для хранения данных. Если я слишком много читаю и отправляю слишком много, я не получаю никакой пользы, потому что пакеты фрагментированы. Я хочу только прочитать точный MTU и отправить только эту сумму, чтобы я не хранил много данных в ОЗУ. –

0

Если вы используете UDP, вам может потребоваться фрагментация, но если да, то почему вы используете свой собственный протокол для передачи больших файлов? Вместо этого используйте TCP и не беспокойтесь об этом. Если вы используете свой собственный протокол через UDP с контролем перегрузок и всеми необходимыми вещами, тогда установите бит DF на пакеты и обработайте ответы.

Если вы используете TCP, вам не нужно беспокоиться о фрагментации вообще, стек делает это для вас.

+0

Я должен был добавить дополнительную информацию. Я использую FTP для отправки файлов. Моя основная проблема заключается в том, что у меня не так много оперативной памяти, поэтому я должен сэкономить объем данных, хранящихся в ОЗУ. –

+1

Сколько стоит «не много RAM»? Если вы не заботитесь о килобайтах (в отличие от мегабайт), вы оптимизируете неправильную вещь. Используя TCP (как вы с FTP), вы должны просто заполнить буфер отправки сокета. Стек TCP/IP будет иметь дело с обнаружением MTU пути и управлением размером окна. На уровне приложения вы даже не видите границы пакетов, давайте их управляем. – janm

+0

Что сказал @janm :) – Thorarin

0

Использовать FtpWebRequest и FtpWebResponse. Дело в том, что эти классы не используют огромные буферы, а потоки (которые реализованы с использованием буфера самого большого размера). Использование памяти будет очень минимальным.

Размер пакета не под вашим контролем, а под сетевым драйвером.

Если вам нужна лучшая скорость, тогда реализуйте передачу данных/прием через класс TcpClient на стороне сервера и клиента.

UPD: Вот пример того, как файлы должны быть загружены: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx См. class AsynchronousFtpUpLoader.

Еще одна вещь. Некоторое время назад я экспериментировал с MTU. Все мои изменения снизили скорость передачи данных. Сетевой драйвер Windows достаточно умен, чтобы использовать лучший MTU.

+0

Мой FTP-сервер такой обычай, кровавая вещь заставляет FtpWebRequest зависать из-за плохих терминаторов. Я хотел бы заменить сервер FTP более стандартным сервером, но он работает в некоторых встроенных аппаратных средствах, поэтому я не могу его коснуться. –

+0

Ну. Что я могу сказать ... Ваша жизнь отстой. :) –

0

PMTU Discovery используется вами TCP-стек исключительно для оптимизации размера пакета при отправке. На вашем уровне вы видите только поток (т.е.прежде чем пакетирование даже произойдет, не говоря уже о фрагментации). То, что вы действительно проблема, похоже на то, что вы пытаетесь отправить данные, как можете, однако вы подключаетесь к TCP/IP медленнее, так что это вызывает пространство, необходимое для создания ram. Поскольку вы используете FTP, я бы ожидал, что реализация FTP, которую вы используете, уже поддерживает и понимает это ??? Поскольку вы запрашиваете буферы, это похоже на рулон, который вы используете на основе сокета или что-то в этом роде. Если вы используете синхронные методы отправки, когда буфер сокета заполнен, он должен блокировать отправку, пока он не будет иметь буферное пространство.

Можете ли вы дать более подробную информацию о том, какие API вы используете для отправки файла, Builtin vs. roll, который у вас есть? Будь то сокет, сетевой поток и т. Д.?