Bonjour — это технология, которая делает поиск услуг очень простым. Несмотря на свою мощь и простоту использования, он не получает большого внимания в сообществе какао. Bonjour очень хорошо работает с библиотекой CocoaAsyncSocket, библиотекой с открытым исходным кодом, которая предоставляет интерфейс Objective-C для работы с сокетами на iOS и OS X. В этой серии я познакомлю вас с Bonjour и библиотекой CocoaAsyncSocket, создав простую, сетевая игра. Попутно я познакомлю вас с миром сетевых технологий, обсуждая протоколы TCP и UDP, а также сокеты, потоки и порты!
Вступление
В этой серии мы создадим простую сетевую игру. Нашим основным фокусом будет сетевой аспект игры. Я покажу вам, как соединить два устройства, используя Bonjour и мощную библиотеку CocoaAsyncSocket. Игра, которую мы создадим, позволяет двум людям в одной сети соревноваться друг с другом. Сама игра не будет очень продвинутой, поэтому не ожидайте графически богатого FPS.
В этой серии я не буду говорить об инфраструктуре, которая позволяет сетевым приложениям взаимодействовать друг с другом. Вместо этого я сосредоточусь на протоколах и технологиях, которые составляют основу сетевых приложений. Базовое понимание протоколов, сокетов и потоков TCP и UDP неоценимо для любого разработчика, особенно для тех, кто планирует создавать приложения, основанные на подключении к сети. Даже если вы не собираетесь использовать Bonjour, я настоятельно рекомендую прочитать оставшуюся часть этой статьи, чтобы лучше понять работу в сети.
В этой статье я рассмотрю несколько ключевых компонентов сетевых приложений. Это поможет вам понять, как работает Bonjour, что такое Bonjour (а что нет), а также значительно упростит работу с библиотекой CocoaAsyncSocket.
Имейте в виду, что Bonjour не требуется для разработки сетевого приложения. Большинство операционных систем на основе Unix, таких как iOS и OS X, используют сокеты BSD в качестве основного интерфейса сетевого программирования. На iOS и OS X библиотека BSD Socket легко доступна. Работа с библиотекой BSD Socket, однако, не для слабонервных и требует глубоких знаний программирования сокетов и языка Си. В iOS и OS X вы также можете использовать низкоуровневую инфраструктуру CFNetwork , которая является прямым расширением для сокетов BSD. Apple разработала инфраструктуру CFNetwork, чтобы упростить сетевое взаимодействие, избегая прямого взаимодействия с сокетами BSD. Одним из наиболее важных преимуществ CFNetwork является встроенная поддержка интеграции цикла выполнения. CFNetwork является частью платформы Core Foundation и написана на C.
Удивительное число разработчиков iOS и OS X настолько привыкли к синтаксису Objective-C, что они избегают библиотек и сред, написанных на C. Если вы один из тех разработчиков, то среда CFNetwork может показаться устрашающей. Тем не менее, есть решение для этого, и его имя CocoaAsyncSocket . Библиотека CocoaAsyncSocket упрощает взаимодействие с сокетами, а также предоставляет элегантный интерфейс Objective-C. Текущая версия библиотеки CocoaAsyncSocket аккуратно интегрируется с Grand Central Dispatch (GCD), что облегчает асинхронное программирование.
Давайте начнем с изучения основ сети. Без хорошего понимания сокетов, портов и потоков, даже Bonjour и библиотека CocoaAsyncSocket не будут вам полезны!
Основы сети
Под капотом
Сетевое взаимодействие не легко, и это то, что не изменится в ближайшее время. Несмотря на то, что инфраструктура, которая дает нам доступ к Интернету, сильно изменилась за последние несколько десятилетий, базовые технологии и протоколы изменились очень мало. Причина в том, что службы, которые мы используем ежедневно, в значительной степени полагаются на базовые логические протоколы и гораздо меньше на физическую инфраструктуру. В девяностые годы большинство из нас просматривали веб-страницы через модемное соединение. В настоящее время большинство людей имеют доступ к быстрому широкополосному соединению, и в последние несколько лет значительная часть Интернета стала потребляться через мобильные устройства. Другими словами, инфраструктура сильно изменилась, но логические протоколы, необходимые для маршрутизации трафика и взаимодействия с приложениями, изменились не так сильно.
Никогда не меняй выигрышную команду
Другая причина того, что фундаментальные технологии и протоколы, которые мы используем для передачи данных в Интернете, не сильно изменились, заключается в том, что они доказали свою надежность, производительность и надежность. Эти технологии и протоколы хорошо проверены, и они зарекомендовали себя бесчисленное количество раз за последние несколько десятилетий.
Сокеты, потоки и порты
Как разработчик, вы, вероятно, слышали о сокетах, портах, адресах и тому подобном. Если вы не знакомы с этими условиями, то вас ждет удовольствие, так как я познакомлю вас с чудесами сокетов, портов, потоков и протоколов. Чтобы получить общее представление о работе с сетями, важно знать основы сети, включая сокеты и их друзей.
Локальные и удаленные розетки
Сетевое соединение работает через сокеты. Сокет — это один конец канала связи между двумя процессами, которые хотят общаться друг с другом. Как вы уже догадались, сетевое соединение (или межпроцессный канал связи) имеет два разъема, по одному для каждого конца канала. Сетевое соединение устанавливается одним сокетом, устанавливающим соединение с другим сокетом, сокетом прослушивания, который прослушивает входящие соединения.
Разница между локальным и удаленным сокетом просто семантическая. С точки зрения сокета, сокет является локальным сокетом, а сокет, к которому он подключен, является удаленным сокетом. Это имеет смысл. Правильно?
В то время как сокет используется для отправки и получения данных, поток может либо читать данные, либо записывать данные. Это означает, что в большинстве случаев каждый сокет имеет два потока: один для чтения и один для записи. Несмотря на то, что потоки являются важным аспектом программирования сокетов, мы не будем работать с потоками напрямую, поскольку потоки управляются для нас библиотекой CocoaAsyncSocket.
Установление сетевого подключения
Каждый сокет имеет адрес, который состоит из адреса хоста и номера порта . Обе части необходимы для установления соединения между двумя розетками. Для простоты, адрес хоста обычно является IP-адресом (интернет-протокола) машины, а номер порта однозначно определяет сокет на машине. Сравните эту концепцию с жилым комплексом. У здания есть адрес, чтобы люди знали, где его найти. Каждая квартира в здании имеет уникальный номер, поэтому посетители комплекса могут найти квартиру, которую они ищут.
Протоколы передачи
Передача данных через Интернет является сложным процессом, в результате которого были созданы два надежных протокола для равномерной отправки и получения данных: TCP ( протокол управления передачей ) и UDP ( протокол дейтаграмм пользователя ). Оба протокола являются протоколами транспортного уровня и являются частью пакета Интернет-протокола (IP).
Я уверен, что TCP и UDP звонят в звонок большинству из вас. Существует несколько ключевых различий между обоими протоколами, и важно понимать эти различия. В этой серии мы сосредоточимся на протоколе TCP. TCP-соединение управляет потоком данных от одной конечной точки к другой.
Надежность сети
Ключевыми отличиями между TCP и UDP являются скорость и то, как они справляются с надежностью сети . Если вы хотите убедиться, что то, что отправлено через один конец соединения, выходит на другом конце, то TCP — ваш друг. TCP медленнее, чем UDP, но у него есть веская причина для того, чтобы быть медленнее. Не вдаваясь в подробности, важно знать, что TCP устанавливает и завершает соединение при рукопожатии, чтобы идентифицировать оба конца соединения. Это также гарантирует, что каждый пакет, отправленный через канал, поступает на другой конец. Кроме того, TCP гарантирует, что порядок пакетов соблюдается.
Одна из причин того, что UDP быстрее, чем TCP, заключается в том, что он не требует рукопожатия при установлении и прекращении соединения. Кроме того, протокол UDP не заботится о прибытии пакета, а также не заботится о порядке поступления пакетов. Если по пути отбрасывается пакет, протокол UDP не пытается отправить его повторно, так как он даже не знает об отбрасывании пакета. Основной проблемой UDP является то, что данные передаются по каналу связи как можно быстрее.
Я уверен, что вы начинаете видеть, что TCP и UDP очень разные протоколы, и что каждый протокол служит своей цели. UDP, например, идеально подходит для потоковой передачи аудио и видео в реальном времени. Скорость имеет важное значение в этих ситуациях. Неважно, если пакет будет отброшен по пути. Если отброшенный пакет будет отправлен повторно, он прибудет с опозданием, и для потоковой передачи он больше не будет актуален. Многопользовательские онлайн-игры также выигрывают от UDP. Скорость UDP важнее, чем его надежность. Пакеты, которые приходят слишком поздно, уже не актуальны, и это основная идея UDP — скорость над надежностью.
TCP, с другой стороны, все о надежности. Он используется для электронной почты и просмотра веб-страниц. Это немного медленнее, но будет делать все возможное, чтобы убедиться, что вы получите то, что просили. Протокол TCP очень надежен и поддерживает повторную отправку отброшенных пакетов, а также учитывает порядок отправки пакетов. Хотя в этой серии мы будем использовать протокол TCP, имейте в виду, что библиотека CocoaAsyncSocket также поддерживает протокол UDP.
Клиент и Сервер
С точки зрения сетевого взаимодействия есть еще одна концепция, которую вам необходимо понять: модель клиент-сервер. В каждом сообщении есть клиент и сервер. Сравните эту модель с двумя людьми, звонящими по телефону. Стивен хочет позвонить Люси. Для этого есть три основных требования.
- Первое требование состоит в том, что Стивен знает о Люси, и ему нужно знать номер телефона Люси. То же самое верно для клиента, пытающегося подключиться к серверу. Клиент должен знать о существовании сервера, и он должен знать адрес сервера.
- Однако обратное неверно. Люси не нужно ничего знать о Стивене, чтобы Стивен позвонил Люси. Другими словами, серверу не нужно знать о существовании клиента, чтобы клиент мог подключиться к серверу.
- Как только соединение установлено, Стивен может поговорить с Люси, а Люси — со Стивеном. Когда клиент подключен к серверу, клиент может отправлять данные на сервер, а сервер может отправлять данные клиенту.
Эта концепция клиента и сервера станет важной, когда мы рассмотрим Bonjour на практике в следующей статье этой серии. Давайте закончим этот урок, кратко рассмотрев Bonjour.
Где Bonjour подходит?
Что такое Bonjour и как он вписывается в нашу историю? Bonjour — это технология, созданная Apple и основанная на Zeroconf . Его основная цель — облегчить обнаружение сервисов. Скорее всего, вы использовали Bonjour много раз, даже не подозревая об этом. Вы когда-нибудь использовали принтер в своей локальной сети? Вас не поразило, что принтер почти не потребовал усилий, даже если он не был физически подключен к вашему компьютеру? Приложение Apple Remote для iOS также использует Bonjour, как и многие другие приложения для iOS и OS X.
Хотя Bonjour — отличная технология, имейте в виду, что она не заботится об отправке или получении данных. Bonjour очень хорошо делает, публикуя и обнаруживая сервисы, которые находятся в одной локальной сети. В следующей статье мы подробнее рассмотрим API Bonjour и начнем строить модель клиент-сервер, о которой мы говорили в этой статье.
Вывод
В этом вводном учебном пособии вы должны иметь общее представление о создании сетей, различных задействованных компонентах и роли каждого компонента. В остальных частях этой серии мы повторно рассмотрим и используем некоторые из этих компонентов, поэтому важно, чтобы вы поняли, что мы рассмотрели в этой статье. В следующей статье я подробнее расскажу о модели клиент-сервер и покажу, как соединить два устройства с помощью Bonjour и библиотеки CocoaAsyncSocket.