2010-10-07 3 views
5

Как создать клиентский UDP-сокет на C++, чтобы он мог прослушивать порт, который прослушивается другим приложением? Другими словами, как я могу применить мультиплексирование портов в C++?C++ UDP Socket port multiplexing

+0

Зачем вам это делать? – jweyrich

+0

Мультиплексирование полезно только в том случае, если другой конец сокета ожидает мультиплексированных данных (если вы не пытаетесь «подделать» данные, которые ожидает другой конец). – dreamlax

+0

Думаю, я должен объяснить сценарий немного лучше. У меня есть приложение, работающее на порту 5000. Я хочу прослушивать один и тот же порт, чтобы я мог получать и анализировать все пакеты, которые получает приложение. Я думал, что могу использовать опцию SO_REUSEADDR для привязки сокета, но это WAITS для первоначального приложения закрыть до того, как моя программа получит пакеты на одном и том же порту. Надеюсь, теперь вопрос и желаемое поведение будут ясны. Спасибо за ответ. – SkypeMeSM

ответ

3

Я хочу слушать только один порт

Вы можете сделать это с помощью сниффера. Просто игнорируйте пакеты из разных портов.

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

Хорошо, здесь я предлагаю вам отказаться от сниферов, и использовать MITM техника.

Вы должны полагаться на правила брандмауэра в PREROUTING к отбракованных пакеты в «прокси» приложения. Если предположить, UDP, Linux, IPTables и «прокси» работает на том же хосте, вот что «прокси» на самом деле нужно сделать:

1. Добавьте правило брандмауэра отбракованных в пакеты (сделать это вручную, если вы предпочитаете):

iptables -t nat -A PREROUTING -i <iface> -p <proto> --dport <dport> 
    -j REDIRECT --to-port <newport> 

2. Bind и слушать на <newport>.

3. Передача всего трафика между двумя конечными точками (клиентом и исходным пунктом назначения).Если вы используете «прокси» на другом хосте, используйте getsockopt с SO_ORIGINAL_DST, чтобы получить исходный адрес назначения.

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

+0

Я думаю, это именно то, что мне нужно. :) Большое спасибо. – SkypeMeSM

1

Это не мультиплексирования - этот термин зарезервирован для обработки ввода/вывода по нескольким каналам в том же процессе, и где такие вещи, как select(2) и poll(2) являются наиболее полезными.

Что вы запрашиваете, это multicast. Here является основным примером.

Обратите внимание, что IP резервирует специальный диапазон адресов (группы a.k.a.) для многоадресной рассылки. Они сопоставляются с особыми адресами ethernet. У слушателя (ов) должно быть присоединить группу многоадресной передачи, в то время как отправитель не должен, он просто отправляет, как обычно.

Надеюсь, это поможет.

+0

У меня есть программное приложение, работающее на порту 5000, и я не могу изменить это приложение, чтобы оно соединяло любую группу многоадресной передачи или аналогично. Я хочу прослушивать один и тот же порт, чтобы мой код мог анализировать все пакеты, полученные этим приложением. У меня было мнение, что это называется «мультиплексирование портов», но я не могу найти подходящий пример для него. – SkypeMeSM

+0

Затем получите Wireshark (http://www.wireshark.org/), обнюхивайте пакеты, сбрасывайте в файл и отправляйтесь на него. –

+0

Я использую wirehark для просмотра пакетов в автономном режиме, но мне нужно написать программу на C++, которая нюхает или слушает на определенном порту, а не на всех портах, и не может быть отключена. Я могу использовать библиотеку libpcap, но, как я уже сказал, я хочу слушать только один порт, и мне может потребоваться остановить его от отправки некоторых определенных пакетов, потому что моя программа отправит его вместо исходного приложения! Я не уверен, что я вас смущаю :) – SkypeMeSM

2

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

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

+0

Хорошо. Итак, по вашему мнению, единственная альтернатива - использовать libpcap для обнюхивания каждого пакета в сетевом интерфейсе, а затем отфильтровывать пакеты для этого конкретного порта. Я думал, что, поскольку это UDP-пакеты (без подключения), не должно было быть проблемой пассивно/активно отправлять/получать пакет на одном и том же порту. – SkypeMeSM

+0

Я пробовал, Linux только доставляет в первый сокет, он не мультиплексирует одноадресные пакеты. Другие платформы могут, но вряд ли будут отличаться по соображениям производительности. –