2016-05-11 5 views
0

У меня есть код, который работает с помощью предварительных сокетов (через. BSD API), а затем в более позднее время, когда адрес известен, он будет делать connect() и т. д. Это работает с IPv4, но теперь я рефакторинг поддерживаю IPv6.Предварительно создающие сокеты, не зная, являются ли они IPv4 или IPv6

Проблема в том, что кажется, что когда я делаю начальный сокет(), мне нужно поставить AF_INET или AF_INET6. Однако, поскольку я еще не знаю адрес, я не знаю, что правильно. Есть ли способ создать универсальный сокет, который будет работать? Если я использую AF_INET6, и я нахожусь в сети IPv4, могу ли я предположить, что это не сработает?

Связанный с нами вопрос - Несмотря на то, что я еще не знаю IP-адрес, возможно ли, что я могу определить, в какой сети подключено мое устройство: IPv4 или IPv6? Предполагая, что один сетевой интерфейс, я думаю, что я могу быть только одной из этих сетей, поэтому, если я смогу найти способ определить, в какой сети подключено мое устройство, я могу это сделать в момент создания сокета.

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

Я пишу код, который работает на iOS, но я не уверен, что это актуально здесь.

+1

Некоторые платформы поддерживают * двойные стеки * сокеты (к сожалению, iOS не является одним из них, особенно с Apple, подталкивающим iOS к поддержке только IPv6). Где доступно, вы можете создать сокет 'AF_INET6' для IPv6, а затем отключить опцию' IPV6_V6ONLY', чтобы разрешить IPv4 через [IPv4-отображаемые адреса IPv6] (https://en.wikipedia.org/wiki/IPv6#IPv4 -mapped_IPv6_addresses). –

ответ

5

Что вы хотите сделать, это невозможно. Когда сокет создается, он связан с протоколом стека, а IPV6 и IPV4 - это просто разные протоколы стека.

Тем не менее, реальный вопрос: Почему ли вы предопределяете розетки? Почему бы не создать сокет, когда вам нужно?

И последнее, но не в последнюю очередь, ваше предположение неверно. Устройство может иметь несколько интерфейсов - один для IPv4, другой для IPv6 - и использовать их оба.

+2

Правильный ответ, не знаю, почему кто-то дал вам -1 ... –

+0

@SanderSteffann, да, мне тоже любопытно. – SergeyA

+0

Возможно, это был хороший ответ (я ** не проголосовал), но я не уверен, что он охватывает все ... как насчет использования семейства сокетов 'AF_UNSPEC', что позволяет привязывать протокол к ожиданию для 'bind' ... Я знаю, что это относится к сокетам прослушивания (я могу слушать как IPv4, так и IPv6), но может быть полезно объяснить, как это применимо (или не применяется) к клиентскому сокету. – Myst