Техническое примечание TN2152

Стратегии передачи документа

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

Прежде всего этот technote адресует разработчиков, работающих над iOS. Однако многие методы, описанные в настоящем документе, применяются одинаково хорошо к Mac OS X, поэтому даже разработчики, работающие исключительно над Mac OS X, могли бы счесть его интересным.

Введение
Сетевые проблемы с общими решениями
Сетевые проблемы с архитектурно-зависимыми решениями
На TLS
Сети проектов
Решения для централизованных проектов сервера
Решения для одноранговых проектов
Проблемы протокола
Протоколы передачи файлов
Синхронизация проблем
История версии документа

Введение

Для многих приложений для iOS нужна возможность передать данные между компьютером пользователя и их устройством на iOS, или между двумя устройствами на iOS. Например:

Начиная с iOS 3.2 на iPad Apple представил технологию совместного доступа к файлам (UIFileSharingEnabled) это позволяет приложению представлять свой каталог Documents пользователю через iTunes. Пользователь может тогда переместить файлы назад и вперед между их устройством и их компьютером. Кроме того, iOS 4 принес эту функцию и к iPhone и к iPod touch.

Можно узнать больше о совместном доступе к файлам iTunes в Разделе поддержки Совместного доступа к файлам Новые функции и возможности в iPhone OS.

совместный доступ к файлам iTunes, однако, не решает все проблемы передачи документа. Например:

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

Остаток от этого документа описывает проблемы, которые необходимо решить, два стандартных проекта, которые можно использовать для рассмотрения тех проблем и в каждом проекте, определенные методы, которые можно использовать. Существует акцент на технологии Apple, но необходимо иметь в виду, что при предназначении для общих пользователей iOS компьютер пользователя может быть Windows PC.

Сетевые проблемы с общими решениями

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

Надежность

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

Предпочтительным оружием здесь является TCP. При открытии соединения TCP между двумя сетевыми коллегами Вам гарантируют один из двух результатов:

  • данные, которые Вы отправляете, будут переданы неповрежденные и в порядке, или

  • соединение повредится

TCP заботится обо всех трудных подробных данных, требуемых сделать эту работу; если Вы не сетевой эксперт, необходимо избежать заново изобретать это определенное колесо и использовать TCP или некоторый протокол более высокого уровня, разделенный на уровни поверх TCP, для связи.

Пропускная способность

Каждая сеть имеет предел на сумму данных, которые можно переместить через сеть на единицу времени. Беспроводные глобальные сети (WWANs) представляют собой серьезную проблему пропускной способности; т.е. пропускная способность WWAN является низкой по сравнению с типичным размером данных современного приложения. Необходимо помнить это ограничение при разработке приложения.

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

Задержка

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

В зависимости от сетевого протокола Вы используете, задержка может серьезно повлиять на Вашу производительность сети. Например, скажем, Вы хотите переместить пять пакетов данных от одной машины до другого. У Вас есть два проектных решения:

  1. отправьте № 1, ожидайте ack, отправьте № 2, ожидайте ack и т.д.

  2. отправьте № 1 через № 5, ожидайте всего acks

Кто-то плохо знакомый с сетями мог бы выбрать опцию 1, потому что проще реализовать; это было бы ошибкой. Рассмотрите то, что происходит, если задержка цикла обработки составляет 200 мс (типичное значение в более широком Интернете). Опция 1 займет по крайней мере одну секунду для передачи этих пяти пакетов, независимо от сетевой пропускной способности. Альтернатива, опция 2, передаст те же данные в немногим более, чем 200 мс.

Задержка является особенно плохой проблемой на WWANs. Текущая технология WWAN будет обычно представлять задержку на 200-300 мс в первом транзитном участке!

Вредоносная атака

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

iOS менее уязвим для этого вида проблемы, чем Mac OS X, потому что iOS надевает строгие пределы, какая память в Вашем процессе может быть выполнена как код. Не используйте это в качестве оправдания быть удовлетворенными об этой проблеме! Злонамеренные атакующие постоянно находят новые способы использовать ошибки как это.

Сетевые проблемы с архитектурно-зависимыми решениями

Любой сетевой код должен иметь дело с определенным набором основных проблем. Некоторые из этих проблем могут только быть решены в контексте Вашей полной архитектуры. Следующие подразделы описывают эти проблемы; их решения описаны в более поздних разделах, обсуждающих определенные сетевые проекты.

Открытие службы

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

Посмотрите Решения Для Централизованных Проектов Сервера для получения информации об открытии службы в централизованной серверной архитектуре и Решения Для Одноранговых Проектов для получения информации об одноранговом открытии службы.

Авторизация

Очевидно, что Ваше приложение должно авторизовать свою связь: Ваше приложение является опекуном данных пользователя — это не должно передавать те данные просто никому.

То, что менее очевидно, - то, что авторизация должна быть взаимной. Если Вы плохо знакомы с сетями, Вы могли бы реализовать протокол авторизации как:

  1. клиент соединяется с сервером

  2. клиент отправляет пароль

  3. сервер проверяет пароль и, если это неправильно, разъединения

  4. если сервер не разъединялся, клиент отправляет данные

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

Хуже все же, у самозванца теперь есть копия пароля пользователя, который особенно плох, если, как много людей, пользователь использует тот же пароль для множества служб.

Решение полной проблемы авторизации будет зависеть от Вашего сетевого проекта, как описано в Решениях Для Централизованных Проектов Сервера и Решениях Для Одноранговых Проектов.

На-проводном конфиденциальность

Необходимо предположить, что злонамеренные пользователи смотрят на каждую часть данных, которые Вы передаете по сети. Если Вы когда-нибудь передаете какие-либо данные, которые можно было бы считать персональными наименьшим количеством способа, необходимо гарантировать, что эти данные шифруются на проводе.

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

Точные подробные данные Вашего решения проблемы конфиденциальности будут зависеть от Вашего полного сетевого проекта; посмотрите Решения Для Централизованных Проектов Сервера и Решения Для Одноранговых Проектов для подробных данных.

На TLS

Независимо от Вашей полной архитектуры сетевых соединений вероятно, что TLS (т.е. Безопасность Транспортного уровня или ее предшественник, SSL, Уровень защищенных сокетов) будет частью Вашего решения проблем конфиденциальности и авторизации:

Если бы Вы не знакомы с возможностями TLS, это была бы хорошая идея стать так. Я нашел следующие ресурсы, особенно последний, чтобы быть полезным:

Главные особенности TLS:

Рекомендуемый TLS API и на iOS и на Mac OS X является CFStream. Кроме того, можно получить доступ к HTTPS (т.е. HTTP по TLS) через API CFHTTPStream или API NSURLConnection. На Mac OS X можно также использовать Безопасный Транспортный API низшего уровня.

Для получения дополнительной информации об этом APIs посмотрите следующие ресурсы:

Сети проектов

Существует два существенно различных проекта, которые можно использовать для сетевого кода:

Каждый подход имеет свои за и против. Главный недостаток централизованного сервера является самим сервером; необходимо создать и выполнить сервер от имени пользователей. Это может быть грандиозной задачей для маленького разработчика (или, действительно, для крупного разработчика с большим количеством пользователей; спросите команду MobileMe!). Кроме того, это означает, что Вы заканчиваете тем, что хранили пользовательские данные на своем сервере, имеющем все виды дурацких правовых последствий.

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

По контрасту существуют многочисленные недостатки с одноранговым подходом. Первое, и самый твердый избежать, различные проблемы канального уровня. устройства на iOS в настоящее время поддерживают три канальных уровня для сетей (WWAN, Wi-Fi и Bluetooth), и все они представляют собой проблемы для однорангового использования. Они обсуждены подробно в последующих разделах.

Наконец, TLS был действительно разработан с централизованной моделью сервера в памяти, и использование ее одноранговым способом хитро. Не невозможно заставить его работать, но Вы определенно плаваете против потока.

Проблемы канального уровня WWAN

Не возможно сделать одноранговый по WWAN по ряду причин:

  • Если одна из коллег будет также связана с сетью Wi-Fi, то iOS будет обычно закрывать интерфейс WWAN и отправлять все данные через Wi-Fi.

  • В целом iPhone только включит свой интерфейс WWAN, если он будет использоваться. Это делает его непрактичным для прислушиваний к входящим соединениям в интерфейсе WWAN.

  • Устройства на различных технологиях WWAN (например, EDGE по сравнению с 3G) могут быть в различных сетях.

  • Даже если ни одно из вышеупомянутого не применяется, сотовые поставщики услуг обычно предотвращают одноранговую связь WWAN как меры безопасности.

Проблемы канального уровня Wi-Fi

Если две коллеги находятся на той же сети Wi-Fi, они могут обычно связываться одноранговый. Существуют, однако, проблемы с этим:

  • Некоторые горячие точки Wi-Fi предотвращают одноранговую связь как меры безопасности.

  • Не всегда просто получить две коллеги на той же сети Wi-Fi. Например, если Вы в горячей точке, Вам, вероятно, придется оплатить за доступ, и платеж снова именно так, можно синхронизировать iPhone к Mac, является меньше, чем идеал.

Другая опция на передней стороне Wi-Fi является оперативной сетью (IBSS). Проблемы с этим включают:

  • Нет никакого способа создать такую сеть из устройства на iOS, делающего ее непрактичной для связи от устройства к устройству.

  • Большинство коллег не может быть и на основанном на инфраструктуре и на специальной сети одновременно, которая может сделать вещи очень неудобными. Продолжать пример выше, имея необходимость взять Ваш Mac от сети горячей точки только для синхронизации с iPhone - меньше, чем идеал.

Проблемы канального уровня Bluetooth

iOS 3.0 и более поздняя поддержка одноранговые сети через Bluetooth. В то время как это - большая технология, она все еще имеет много глюков:

  • Это требует iOS 3.0 или позже.

  • Сети Bluetooth не доступны на определенных аппаратных средствах (в частности, iPhone первого поколения и iPod touch).

Важное последствие первой точки - то, что Bluetooth одноранговые сети может только использоваться для передачи между устройствами на iOS; Вы не можете использовать его, например, для передачи между устройством на iOS и компьютером рабочего Mac OS X.

Решения для централизованных проектов сервера

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

Открытие службы

Обнаружение централизованного сервера тривиально: просто присвойте свой сервер, который фиксированный DNS называет и соединяет то имя DNS проводами в Ваши клиенты. Проблема решена!

Авторизация

Как обсуждено выше, существует два аспекта к проблеме авторизации:

  • клиент/сервер — клиент должен проверить, что он говорит с правильным сервером.

  • сервер/клиент — сервер должен авторизовать клиент.

С централизованным сервером клиент-серверная проблема имеет простое решение: TLS! Как часть установки Вашего сервера необходимо создать идентификационные данные TLS для того сервера и подписывать его связанный сертификат одним из центров сертификации, которым доверяет iOS. Затем когда клиент соединится с сервером, механизм TLS гарантирует, что это соединилось с корректным сервером.

Авторизация сервера/клиента более хитра, и решение, которое Вы используете в основном, зависит от серверной инфраструктуры, которую Вы имеете в наличии. Например, Вы могли бы быть в состоянии осуществить контрейлерные перевозки от инфраструктуры авторизации, поддерживаемой узлом Вашего сервера, или Вы могли использовать идентификационные данные клиентской стороны TLS, или Ваш мог использовать основанный на простом пароле механизм авторизации. Существует большой выбор, и трудно выбрать, что использовать, не зная определенные подробные данные Вашего сервера.

На-проводном конфиденциальность

Если Вы используете TLS, и Ваш централизованный сервер имеет идентификационные данные, сертификат которых подписывается доверяемым корнем, Вы получаете на-проводном шифрование автоматически.

Аренда инфраструктуры

Как отмечалось ранее, самая твердая часть о реализации централизованного сервера фактически развертывает сервер. Однако Вы не должны позволять этому препятствовать Вам. Существует множество служб, которые могут помочь Вам с этим. Например:

  • MobileMe и iDisk — Если Вы просто хотите загрузить и загрузить файлы на некоторый легкодоступный центральный сервер, очень просто сделать это использование iDisk пользователя. Помните, что iDisk является просто сервером WebDAV, и WebDAV является просто HTTP, таким образом загружение или загружение файла являются просто простой транзакцией HTTP.

    Одна хорошая функция этого подхода - то, что пользователь разрешает использовать их учетные данные MobileMe, которые очень просто объяснить.

    Главный недостаток этого подхода - то, что пользователь должен подписаться на MobileMe.

  • Другие Службы — Для чего-то более сложного Вы могли использовать одного из многих провайдеров бэкэнда для реализации службы. Два известных примера:

    но существуют многие, еще много.

Решения для одноранговых проектов

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

Открытие службы

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

Можно также сделать открытие службы через GameKit, по очереди использующий Добрый день.

Авторизация

Нет никакого очевидного пути к реализации авторизации в одноранговом случае; пространство решения является широко открытым. Хороший подход должен разработать Ваш пользовательский интерфейс сначала и затем реализовать систему авторизации на основе этого. Проекты общего пользовательского интерфейса включают:

  • аутентифицируйте каждый раз — Каждый раз пользовательские подключения к службе, они должны обеспечить свои учетные данные (по крайней мере, пароль, но во многих случаях имя пользователя также). Можно сделать это немного больше удобным для пользователя путем хранения пароля в цепочке для ключей на клиенте.

    Почтовое приложение iOS использует этот пользовательский интерфейс.

  • аутентифицируйте в первый раз — Во время первого соединения, пользователь должен ввести некоторые учетные данные, и тот процесс генерирует маркер авторизации, использующийся для последующих соединений. Этот подход обычно упоминается как соединение.

    Удаленное приложение iOS использует этот пользовательский интерфейс.

  • аутентифицируйте никогда — Это - еще более простой вариант вышеупомянутого, где пользователь не должен даже аутентифицировать в первый раз вокруг. Вместо этого первое соединение заставляет клиент и сервер соединяться. Это допускает очень простой пользовательский интерфейс, который полностью безопасен кроме во время фазы установки.

Создание идентификационных данных

Как отмечалось ранее, TLS действительно разработан для использования с централизованными серверами и не является хорошим соответствием для одноранговых сетей. Ключевая проблема состоит в том, что TLS основывается на идентификационных данных X.509, и эти идентификационные данные, как ожидают, будут содержать имя DNS удаленного узла и будут подписаны доверяемым корнем. Ни одно из этих требований не практично в одноранговом сетевом проекте.

Возможно использовать TLS в проекте одноранговой сети; просто необходимо изогнуть правила немного. Идея состоит в том, чтобы отключить автоматическую проверку сертификата, сделанную TLS и проверить равноправный сертификат самостоятельно. В этой модели Вы не должны действительно смотреть в сертификате; все, что необходимо сделать, должно сравнить сертификат известному хорошему сертификату, который Вы получили во время соединения.

Основной камень преткновения - то, что у каждой коллеги должны быть уникальные идентификационные данные X.509, и создание таких идентификационных данных хитро. В настоящее время нет никакого прямого APIs для создания идентификационных данных на iOS или Mac OS X. Однако существует много способов обойти это ограничение:

  • Имейте некоторую централизованную проблему сервера идентификационные данные, возможно с помощью чего-то как Simple Certificate Enrollment Protocol (SCEP). Эти идентификационные данные могут быть самоподписаны или подписаны идентификационными данными, связанными с сервером.

  • Генерируйте самоподписанные идентификационные данные на коллегах. В то время как нет никакого хорошего APIs для того, чтобы сделать это, можно создать идентификационные данные на Mac OS X путем подзапуска openssl инструмент командной строки.

На-проводном конфиденциальность

Даже в одноранговой ситуации, TLS дает определенную степень на-проводном конфиденциальности независимо. В частности TLS защитит от стороннего отслеживания Вашего трафика. Это автоматически не защитит Вас от спуфинга сервера (или, действительно, атаки «человек посередине»); Вы обычно получали бы такую защиту как результат Вашего процесса соединения.

На GameKit

GameKit адресует некоторых, но не все, проблем, связанных с одноранговыми сетями. Самое главное это обеспечивает простой способ сделать сети по Bluetooth, решающему многие проблемы, связанные с одноранговыми сетями по Wi-Fi. Это также заботится об открытии службы для Вас. Однако это не адресует ни одной из проблем безопасности, описанных выше и, главное, это делает его тяжелее для решения этих проблем, потому что нет никакого простого способа использовать TLS для защиты сеанса GameKit.

Проблемы протокола

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

В зависимости от Вашей серверной архитектуры это может быть надуманным вопросом. Например, при использовании Google App Engine для сервера транзакции должны обязательно быть структурированы в HTTP. В отсутствие таких ограничений необходимо рассмотреть следующие моменты:

Протоколы передачи файлов

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

Если Вы хотите поддерживать протокол организации общего доступа к файлам, наиболее очевидным выбором является WebDAV и SMB. Однако, это не просто. Нет никакого высокоуровневого APIs для этих протоколов на iOS или Mac OS X, несмотря на то, что WebDAV разделен на уровни поверх HTTP так различный HTTP, APIs делает реализацию WebDAV проще.

Синхронизация проблем

Другая общая высокоуровневая цель состоит в том, чтобы синхронизировать структуры данных между двумя или больше машинами. Как только Вы создали соединение надежной и защищенной сети между своими машинами, можно начать думать о том, что оно взяло бы для синхронизации данных между ними.

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

Независимо от Ваших потребностей синхронизации необходимо будет записать весь этот код сами. iOS не предоставляет определенной высокоуровневой поддержки для синхронизации (например, нет никакого эквивалента Sync Services на iOS).



История версии документа


ДатаПримечания
26.07.2010

Обновленный для отражения введения совместного доступа к файлам iTunes. Некоторые другие незначительные обновления.

29.01.2010

Незначительное изменение для разъяснения доступности Bluetooth одноранговые сети, плюс различные редакционные тонкие настройки.

25.08.2009

Новый документ, описывающий различные стратегии передачи документа от устройства к устройству и устройства к компьютеру.