8-900-374-94-44
[email protected]
Slide Image
Меню

Сервера udp: Уроки Ардуино. Протокол UDP. Создание UDP-сервера и клиента с помощью библиотеки UIPEthernet.

Отличия TCP и UDP протоколов — выяcняем разницу на примерах

Современный мир завязан на системах связи, когда различные устройства «общаются» между собой посредством «правил», или протоколов модели OSI (Open Systems Interconnection model), определяющей методы взаимодействия. В тексте рассмотрим два самых популярных протокола транспортного уровня — TCP и UDP — и сравним их.

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

TCP — протокол транспортного уровня

Первым из рассматриваемых протоколов будет TCP, или Transmission Control Protocol, который используется для транспортировки сообщений между устройствами в сети.

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

Например, человек хочет скачать картинку. Сервер обрабатывает запрос и высылает в ответ требуемое изображение. Ему, в свою очередь, необходим путь или канал, по которому он будет передавать информацию. Поэтому сервер обращается к сетевому сокету для установки требуемого соединения и отправки картинки. Сервер дробит данные, инкапсулирует их в блоки, которые передаются на уровень TCP получателя при помощи IP-протокола. Далее получатель подтверждает факт передачи.

У протокола TCP есть несколько особенностей:

  • Система нумерации сегментов. TCP отслеживает передаваемые и принимаемые сегменты, присваивая номера каждому из них. Байтам данных, которые должны быть переданы, присваивается определенный номер байта, в то время как сегментам присваиваются порядковые номера.
  • Управление потоком. Функция ограничивает скорость, с которой отправитель передает данные. Это делается для обеспечения надежности доставки, в том числе чтобы компьютер не генерировал пакетов больше, чем может принять другое устройство. Если говорить простым языком, то получатель постоянно сообщает отправителю о том, какой объем данных может быть получен.
  • Контроль ошибок. Функция реализуется для повышения надежности путем проверки байтов на целостность.
  • Контроль перегрузки сети. Протокол TCP учитывает уровень перегрузки в сети, определяемый объемом данных, отправленных узлом.

Примеры применения сетевого протокола TCP

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

  • SSH, FTP, Telnet: в данных протоколах TCP используется для обмена файлами.
  • SMTP, POP, IMAP: протоколы, где TCP отвечает за передачу сообщений электронной почты.
  • HTTP/HTTPS: протоколы, где TCP отвечает за загрузку страниц из интернета.

Эти примеры работают на уровне приложений стека TCP/IP и передают данные вниз к TCP, на транспортный уровень.

Строение протокола TCP

Структура пакета протокола TCP/IP.

В каждый пакет данных TCP добавляет заголовок общим объемом в 20 байт (или октетов), в котором содержатся 10 обязательных полей:

  • Порт источника — порт устройства-отправителя.
  • Порт назначения — порт принимающего устройства.
  • Порядковый номер. Устройство, инициирующее TCP-соединение, должно выбрать случайный начальный порядковый номер, который затем увеличивается в соответствии с количеством переданных байтов.
  • Номер подтверждения. Принимающее устройство увеличивает этот номер с нуля в соответствии с количеством полученных байтов.
  • Сдвиг данных TCP. Данный параметр определяет размер заголовка, чтобы система могла понять, где начинаются данные.
  • Зарезервированные данные — зарезервированное поле, значение которого всегда равно нулю.
  • Флаги управления. TCP использует девять флагов для управления потоком данных в определенных ситуациях — например, при инициировании сброса сессии.
  • Размер окна — самая важная часть заголовка TCP. Это поле используется получателем для указания отправителю объема данных, которые он может принять.
  • Контрольная сумма. Отправитель генерирует контрольную сумму и передает ее в заголовке каждого пакета. Принимающее устройство может использовать контрольную сумму для проверки ошибок в полученном файле.
  • Срочный указатель — это предлагаемая протоколом возможность помечать некоторые байты данных тегом «Срочно» для их пересылки и обработки вне очереди.
  • Поле опции. Может использоваться для расширения протокола или его тестирования.

Ускоряем работу протокола TCP при хорошем соединении или выжимаем максимум

TCP используется при передаче данных в таких протоколах, как HTTP, Telnet, FTP, SMTP. При использовании протокола нужно учесть, что при увеличении потери пакетов время, затрачиваемое на доставку файла, увеличивается.

Чтобы достичь максимальной пропускной способности TCP-соединения, можно выполнить следующие шаги:

Увеличить размер окна. Размер окна, или TCP Window Size, — это количество данных, которое может быть передано в данный момент без подтверждения. Это значение устанавливается в начале соединения между устройствами. Однако это значение можно изменить заранее, введя команду regedit в поиске и перейдя по следующему пути: 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DefaultSendWindow

Увеличение параметра приведет к тому, что уменьшится количество проверок полученных данных и увеличится эффективность использования полосы пропускания. Также, перейдя по пути:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters

, можно добавить значение Tcp1323Opts, которое отвечает за изменение размера окна и управление временной меткой.

Изменение значения SackOpts. SACK, или селективное подтверждение, крайне важно для подключений с большим размером окна. Без этой функции проверка полученных данных выполняется только по последнему номеру последовательности полученных данных. Но с включением этой функции появляется возможность подтверждать получение отдельных блоков. Чтобы изменить данный параметр, можно перейти по пути:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

и выбрать параметр SackOpts. 

Изменение значения TcpMaxDupAcks. Данный параметр отвечает за количество полученных подтверждений о передаче. Стандартное значение состоит из одного подтверждения и двух дубликатов. Параметр можно изменить, перейдя по пути:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

и выбрав TcpMaxDupAcks. Это позволит вам назначать количество требуемых подтверждений для запуска быстрой повторной передачи, что в результате скажется на скорости передачи данных.

Стоит отметить, что данными манипуляциями выигрываются доли секунд, поэтому сильно прироста скорости вы не увидите.

UDP — протокол транспортного уровня

Если нам очень важна скорость передачи, а вот потеря пакетов не так критична (как, например, в голосовом или видеотрафике), то лучше использовать UDP, или User Datagram Protocol. В отличие от TCP он обеспечивает передачу данных без получения подтверждения от пользователя. Проще говоря, просто отправляет пакеты и не ждет ничего в ответ. Из-за этого достигается высокая скорость в ущерб надежности.

Чаще всего UDP применяется в чувствительных ко времени службах, где потерять пакеты лучше, чем ждать. Звонки в Skype или Google Meet, стриминг видео, онлайн-трансляции используют этот протокол из-за того, что они чувствительны ко времени и рассчитаны на определенный уровень потерь. Вся голосовая связь через интернет работает по протоколу UDP. Также UDP очень часто используется в онлайн-играх. Аналогичная история с DNS-серверами, поскольку они должны быть быстрыми и эффективными.

Примеры использования протокола UDP

Примерами протоколов, использующих UDP-протокол, являются:

  • DNS — протокол, преобразующий домены в IP-адреса, чтобы сделать возможной загрузку интернет-ресурса через браузер.
  • SNMP — протокол, позволяющий системному администратору проводить мониторинг, контролировать производительность сети и изменять конфигурацию подключенных устройств.
  • DHCP — протокол, отвечающий за автоматическое назначение IP-адреса клиенту.
Структура пакета протокола UDP.

Разница между TCP и UDP

Ключевым различием между TCP и UDP является скорость, поскольку TCP сравнительно медленнее UDP. В целом, UDP является быстрым, простым и эффективным протоколом, однако повторная передача потерянных пакетов данных возможна только в TCP. 

Еще одно заметное различие между TCP и UDP заключается в том, что первый обеспечивает упорядоченную доставку данных от пользователя к серверу (и наоборот). UDP, в свою очередь, не проверяет готовность получателя и может доставлять пакеты вразнобой.

TCP vs UDP

Рассмотрим разницу характеристик протоколов TCP и UDP.

TCPUDP
Состояние соединенияТребуется установленное соединение для передачи данных (соединение должно быть закрыто после завершения передачи)Протокол без соединения, без требований к открытию, поддержанию или прерыванию соединения
Гарантия доставкиМожет гарантировать доставку данных получателюНе гарантирует доставку данных получателю
Повторная передача данныхПовторная передача нескольких кадров в случае потери одного из нихОтсутствие повторной передачи потерянных пакетов
Проверка ошибокПолная проверка ошибокБазовый механизм проверки ошибок. Использует вышестоящие протоколы для проверки целостности
Метод передачиДанные считываются как поток байтов; сообщения передаются по границам сегментовUDP-пакеты с определенными границами; отправляются по отдельности и проверяются на целостность по прибытии
Сферы примененияИспользуется для передачи сообщений электронной почты, HTML-страниц браузеровВидеоконференции, потоковое вещание, DNS, VoIP, IPTV

Отличия TCP и UDP при использовании в VPN

Также нередко возникает вопрос, касающийся использования данных протоколов при VPN-соединениях. К примеру, в OpenVPN существует возможность выбора между TCP- и UDP-протоколами. 

Условимся, что VPN заворачивает передаваемые данные в еще один протокол (на самом деле все намного сложнее). Если ваш VPN-туннель использует в качестве транспортного протокола TCP, то передача данных по UDP-протоколу теряет свои преимущества. Как минимум на определенном участке пути. Поэтому для VPN-туннеля советуют использовать UDP-протокол, ведь TCP будет штатно работать внутри UDP-туннеля.

Поднимите VPN на сервере Selectel

Более 100 готовых к работе конфигураций.

Выбрать

Итог сравнения протоколов TCP и  UDP 

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

Также серьезным отличием TCP от UDP является размер заголовков. У TCP он составляет 20-60 байт, а у UDP — всего 8 байт. Это показывает, насколько сложнее устроен протокол TCP, ведь он приоритизирует трафик и проверяет блоки данных на наличие ошибок.

Получать текст из UDP-сокета—Обработка данных событий (10.7.1)

Имя

Описательное имя входного коннектора, используемое для справки в GeoEvent Manager.

Пространственная привязка по умолчанию

Известный идентификатор (WKID) пространственной привязки, используемый при построении геометрии из значений полей атрибутов, координаты которых не являются значениями широты и долготы для предполагаемой географической системы координат WGS84, или строки геометрии, не включающие пространственную привязку. Также может быть указано известное текстовое значение (WKT) или имя поля атрибута, содержащего WKID или WKT.

Порт сервера

Порт сервера, используемый при установке сокета UDP. Клиенты UDP должны иметь возможность обнаруживать и подключаться к этому порту. По умолчанию используется порт 5000, но можно использовать любой доступный порт сервера.

Прикрепить исходный IP к сообщению

Указывает, должен ли транспорт добавлять IP-адрес компьютера, отправившего дейтаграмму UDP к дейтаграмме (сообщению). Если указанное свойство Символ префикса IP источника совпадает с Разделителем атрибутов, адаптер будет интерпретировать добавленные значение IP и порт как дополнительное строковое значение атрибута. Убедитесь, что Определение GeoEvent содержит поле атрибута для размещения данных, добавляемых к каждой дейтаграмме.

  • Да – IP-адрес и порт, используемые клиентом для отправки сообщений, будут добавлены к каждой полученной записи события.
  • No – Значения IP-адреса и порта клиента не будут добавляться к каждой полученной записи события.

Символ-префикс исходного IP

(Условия)

Один буквенный символ, используемый транспортом для разделения IP-адреса и номера порта, добавляемых к каждой датаграмме UDP. Обычно используется тот же символ, что и Разделитель атрибутов для значений основного атрибута сообщения, поэтому IP-адрес и порт добавляются в качестве нового атрибута, однако значения IP-адреса и порта могут быть присоединены к конечному строковому значению с помощью другого разделителя.

Это свойство отображается, когда для параметра Прикрепить исходный IP к сообщению задано значение Да, и скрыто, когда параметр Прикрепить исходный IP к определению сообщения настроен как Нет.

Символы для прикрепления к каждому сообщению

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

Размер буфера (байты)

Задает размер буфера, выделяемого транспортом для хранения необработанных байтов, полученных из передающего клиентского приложения UDP. Значение по умолчанию – 2048 байт. Буфер должен быть достаточно большим для размещения IP-заголовков, заголовков UDP, значений атрибутивных данных, строковых представлений геометрии, принимаемых в качестве данных, и любых данных, добавляемых к каждому полученному сообщению.

Разделитель сообщений

Один буквенный символ, который указывает на конец записи данных событий. Значения Unicode могут применяться для указания разделителя символов. Этот символ не должен заключаться в кавычки. Новая строка (\n) является часто используемым разделителем конца записи.

Разделитель атрибутов

Один буквенный символ, используемый для отделения одного значения атрибута от другого в сообщении. Значения Unicode могут применяться для указания разделителя символов. Этот символ не должен заключаться в кавычки. Запятая (,) – общий разделитель атрибутов

Входящие данные содержат определение GeoEvent

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

  • Да – первое поле атрибута в каждой записи события – это имя определения GeoEvent (существующего или нового).
  • Нет – все записи событий имеют общую схему и, следовательно, одно определение GeoEvent. Первое поле атрибута в каждой записи события – это данные датчика, а не имя определения GeoEvent.

Создать определения неопознанных событий

(Условия)

Указывает, следует ли создавать новое Определение GeoEvent, если определение с указанным именем не существует. Если текстовый файл с разделителями содержит записи событий от различных типов датчиков, для указания типа события используется первое значение атрибута, которое берется в качестве имени определения GeoEvent.

  • Да – новое Определение GeoEvent будет создано, если определения события с указанным именем еще нет.
  • Нет – новое Определение GeoEvent не будет создаваться. Данные входящего события, не имеющие соответствующего определения GeoEvent, не могут быть адаптированы и обработаны.

Это свойство показывается, когда для Входящие данные содержат определение GeoEvent задано значение Да, и скрыто, если выбрано значение Нет

Создавать определение GeoEvent

(Условия)

Указывает, следует ли использовать новое или существующее Определение GeoEvent для данных входящих событий. Определение GeoEvent требуется для GeoEvent Server для понимания полей атрибутов и типов данных входящих событий.

  • Да – новое Определение GeoEvent будет создано на основе схемы первой полученной записи события.
  • Нет – новое Определение GeoEvent не будет создаваться. Выберите существующее Определение GeoEvent, соответствующее схеме данных входящего события.

Это свойство показывается, когда для Входящие данные содержат определение GeoEvent задано значение Нет, и скрыто, если выбрано значение Да

Имя определения GeoEvent (новое)

(Условия)

Имя, которое присваивается для нового Определения GeoEvent. Если определение GeoEvent с указанным именем уже существует, будет использоваться существующее определение GeoEvent. Первая полученная запись данных будет использоваться для определения ожидаемой схемы последующих записей данных, на основе которой будет создано новое определение GeoEvent.

Это свойство показывается, когда для свойства Создать определение GeoEvent задано значение Да, и скрыто, если выбрано значение Нет

Имя определения GeoEvent (существующее)

(Условия)

Имя существующего определения GeoEvent для использования при адаптации полученных данных для создания данных событий для обработки сервисом GeoEvent.

Это свойство показывается, когда для свойства Создать определение GeoEvent задано значение Нет, и скрыто, если выбрано значение Да

Построить геометрию из полей

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

  • Да – значения из указанных полей атрибутов событий будут использоваться для построения геометрии точек.
  • Нет – точечная геометрия не будет строится. Предполагается, что поле атрибута содержит значение, которое может быть интерпретировано как геометрия или запись события является непространственной (не имеет геометрии).

Поле геометрии X

(Условия)

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

Это свойство показывается, когда для Построить геометрию из полей задано значение Да, и скрыто, если выбрано значение Нет

Поле геометрии Y

(Условия)

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

Это свойство показывается, когда для Построить геометрию из полей задано значение Да, и скрыто, если выбрано значение Нет

Поле геометрии Z

(Условия)

Имя поля в данных входящего события, содержащего координатную часть Z (например, глубина или высота) местоположения точки. Если оставить пустым, значение Z будет опущено и будет построена 2D геометрия точки.

Это свойство показывается, когда для Построить геометрию из полей задано значение Да, и скрыто, если выбрано значение Нет

Ожидаемый формат данных

Шаблон, используемый для соответствия ожидаемым строковым представлениям значений даты / времени и преобразования их в значения даты Java. Формат шаблона следует нормам для класса Java SimpleDateFormat. Это свойство не имеет значения по умолчанию.

GeoEvent Server предпочитает, чтобы значения даты/времени выражались в стандарте ISO 8601, но несколько строковых представлений значений даты/времени, обычно распознаваемых как значения даты, могут быть преобразованы в значения даты Java без указания Ожидаемого формата даты. В том числе:

  • «2019-12-31T23:59:59» – формат стандарта ISO 8601
  • 1577836799000 – дата Java (epoch long integer; UTC)
  • «Tue Dec 31 23:59:59 -0000 2019» – общий строковый формат веб-сервисов
  • «12/31/2019 11:59:59 PM» – общий формат, используемый в США (12 часов)
  • «12/31/2019 23:59:59» – общий формат, используемый в США (24 часа)

Если полученные значения даты/времени выражены с помощью формата, отличного от одного из пяти, показанных выше, необходимо указать Ожидаемый формат даты, чтобы GeoEvent Server знал, как следует адаптировать значения даты/времени.

Язык форматирования чисел

Идентификатор локали (ID), используемый для чувствительного к локали поведения при форматировании чисел из значений данных. По умолчанию используется локаль компьютера, на котором установлен GeoEvent Server. Дополнительные сведения см. в разделе Поддерживаемые локали Java.

Режим мультикаст

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

  • Да – входной коннектор будет получать пакеты мультикаст, маршрутизируемые на указанный адрес группы.
  • Нет — входной коннектор будет работать как одноадресный (например, точка-точка) приемник. Сообщения должны транслироваться на указанный Порт сервера, используемый для установки UDP-сокета на серверном компьютере под управлением GeoEvent Server.

Группа мультикаст

(Условия)

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

Это свойство показывается, когда для свойства Режим мультикаст задано значение Да, и скрыто, если выбрано значение Нет

Клиент и сервер пользовательских дейтаграмм

Протокол пользовательских дейтаграмм (UDP) работает иначе, чем TCP/IP. Где TCP — это протокол , ориентированный на потоки , гарантирующий, что все данные передается в правильном порядке, UDP представляет собой протокол , ориентированный на сообщения . UDP не требует долговременного соединения, поэтому настройка UDP розетка немного проще. С другой стороны, сообщения UDP должны соответствовать в одном пакете (для IPv4 это означает, что они могут содержать только 65 507 байтов, потому что пакет размером 65 535 байт также включает информацию заголовка) и доставка не гарантируется, как с TCP.

Echo Server

Поскольку соединение отсутствует, серверу не нужно слушать и принимать соединения. Нужно только использовать bind() чтобы связать его сокет с портом, а затем дождаться индивидуального Сообщения.

 импортный разъем
импорт системы
# Создаем сокет TCP/IP
носок = сокет.сокет (сокет.AF_INET, сокет.SOCK_DGRAM)
# Привязать сокет к порту
server_address = ('localhost', 10000)
print >>sys.stderr, 'запуск на %s, порт %s' % server_address
sock.bind (адрес_сервера)
 

Сообщения считываются из сокета с помощью функции recvfrom(), которая возвращает данные, а также адрес клиента, с которого было отправлено.

 пока верно:
    print >>sys. stderr, '\nожидание получения сообщения'
    данные, адрес = sock.recvfrom(4096)
    
    print >>sys.stderr, 'получено %s байт от %s' % (len(data), адрес)
    печать >>sys.stderr, данные
    
    если данные:
        отправлено = sock.sendto (данные, адрес)
        print >>sys.stderr, 'отправлено %s байт обратно на %s' % (отправлено, адрес)
 

Эхо-клиент

Эхо-клиент UDP подобен серверу, но не использует bind() для присоединения своего сокета к адресу. Оно использует sendto() для доставки своего сообщения непосредственно на сервер, и recvfrom() для получения ответа.

 импортный разъем
импорт системы
# Создаем UDP-сокет
носок = сокет.сокет (сокет.AF_INET, сокет.SOCK_DGRAM)
server_address = ('localhost', 10000)
message = 'Это сообщение. Это будет повторяться».
пытаться:
    # Отправить данные
    print >>sys.stderr, 'отправка сообщения "%s"' %
    отправлено = sock.sendto (сообщение, адрес_сервера)
    # Получить ответ
    print >>sys.stderr, 'ожидание получения'
    данные, сервер = sock. recvfrom(4096)
    print >>sys.stderr, 'получено "%s"' % данных
окончательно:
    print >>sys.stderr, 'закрытие сокета'
    носок.закрыть()
 

Клиент и сервер вместе

Запуск сервера производит:

 $ python ./socket_echo_server_dgram.py
запуск на локальном хосте, порт 10000
ожидание получения сообщения
получено 42 байта от ('127.0.0.1', 50139)
Это сообщение. Это будет повторяться.
отправил 42 байта обратно на ('127.0.0.1', 50139)
ожидание получения сообщения
 

и вывод клиента:

 $ питон ./socket_echo_client_dgram.py
отправка «Это сообщение. Оно будет повторено».
ожидание получения
получено "Это сообщение. Оно будет повторено."
закрытие сокета
$
 

сокетов — Python UDP-сервер не получает данные

У меня есть Ethernet-трафик UDP, который я хочу получать на машину (192.168.2.2:7800) (исходящую с отдельной машины (192.168.2.12)).

Я вижу, что данные передаются на принимающую машину, выполнив дамп TCP:

 tcpdump -n -i enp5s0f1 udp порт 7800
tcpdump: подробный вывод подавлен, используйте -v или -vv для полного декодирования протокола
прослушивание на enp5s0f1, тип канала EN10MB (Ethernet), размер захвата 262144 байт
19:04:13. 160763 IP 192.168.2.12.ovbus >
192.168.2.2.asr: UDP, длина 1052 19:04:13.170854 IP 192.168.2.12.ovbus > 192.168.2.2.asr: UDP, длина 1052

Я попытался настроить UDP-сервер Python с IP-адресом 192.168.2.2 и портом 7800, используя следующий код, который я получил здесь от Радослава Матусяка (https://github.com/rsc-dev/pyproxy/blob /master/code/pyproxy.py):

 #!/usr/bin/env Python
__author__ = 'Радослав Матусяк'
__copyright__ = 'Авторское право (c) 2016 Радослав Матусяк'
__license__ = 'MIT'
__версия__ = '0.1'
"""
TCP/UDP-прокси.
"""
импортировать аргументы
сигнал импорта
журнал импорта
импортировать выбрать
импортный сокет
FORMAT = '%(asctime)-15s %(levelname)-10s %(сообщение)s'
logging.basicConfig(формат=ФОРМАТ)
РЕГИСТРАТОР = logging.getLogger()
LOCAL_DATA_HANDLER = лямбда x:x
REMOTE_DATA_HANDLER = лямбда x:x
BUFFER_SIZE = 2 ** 10 # 1024. Сохранить размер буфера как степень 2.
Def udp_proxy (источник, dst):
    """Запустите UDP-прокси.
    
    Аргументы:
    src -- исходный IP-адрес и строка порта.
То есть: "127.0.0.1:8000" dst -- IP-адрес и порт назначения. То есть: "127.0.0.1:8888" """ LOGGER.debug('Запуск UDP-прокси...') LOGGER.debug('Источник: {}'.format(src)) LOGGER.debug('Dst: {}'.format(dst)) proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) proxy_socket.bind (ip_to_tuple (источник)) client_address = Нет server_address = ip_to_tuple(dst) LOGGER.debug('Зацикливание прокси (нажмите Ctrl-Break, чтобы остановить)...') пока верно: данные, адрес = proxy_socket.recvfrom(BUFFER_SIZE) LOGGER.debug('Данные получены') если client_address == None: client_address = адрес если адрес == client_address: данные = LOCAL_DATA_HANDLER (данные) proxy_socket.sendto (данные, server_address) адрес elif == адрес_сервера: данные = REMOTE_DATA_HANDLER (данные) proxy_socket.sendto (данные, client_address) client_address = Нет еще: LOGGER.
warning('Неизвестный адрес: {}'.format(str(адрес))) # конец функции udp_proxy защита tcp_proxy (источник, dst): """Запустить TCP-прокси. Аргументы: src -- исходный IP-адрес и строка порта. То есть: "127.0.0.1:8000" dst -- IP-адрес и порт назначения. То есть: "127.0.0.1:8888" """ LOGGER.debug('Запуск TCP-прокси...') LOGGER.debug('Источник: {}'.format(src)) LOGGER.debug('Dst: {}'.format(dst)) сокеты = [] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind (ip_to_tuple (источник)) s.слушай(1) s_src, _ = s.accept() s_dst = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s_dst.connect(ip_to_tuple(dst)) sockets.append(s_src) sockets.append(s_dst) пока верно: s_read, _, _ = select.select(сокеты, [], []) для s в s_read: данные = s.recv (BUFFER_SIZE) если s == s_src: d = LOCAL_DATA_HANDLER(данные) s_dst.
sendall (д) Элиф с == s_dst: d = REMOTE_DATA_HANDLER (данные) s_src.sendall (д) # конец функции tcp_proxy определение ip_to_tuple (ip): """Разобрать строку IP и вернуть кортеж (ip, port). Аргументы: ip -- IP-адрес: строка порта. То есть: «127.0.0.1:8000». """ ip, порт = ip.split(':') вернуть (ip, int(порт)) # конец функции ip_to_tuple деф основной(): """Основной метод.""" parser = argparse.ArgumentParser(description='TCP/UPD proxy.') # группы TCP UPD proto_group = parser.add_mutually_exclusive_group (обязательно = True) proto_group.add_argument('--tcp', action='store_true', help='TCP proxy') proto_group.add_argument('--udp', action='store_true', help='UDP proxy') parser.add_argument('-s', '--src', required=True, help='Исходный IP-адрес и порт, например: 127.0.0.1:8000') parser.add_argument('-d', '--dst', required=True, help='IP-адрес и порт назначения, например: 127.0.0.1:8888') output_group = parser.
add_mutually_exclusive_group() output_group.add_argument('-q', '--quiet', action='store_true', help='Молчать') output_group.add_argument('-v', '--verbose', action='store_true', help='Говорить громче') аргументы = парсер.parse_args() если args.quiet: LOGGER.setLevel(регистрация.CRITICAL) если args.verbose: LOGGER.setLevel(регистрация.NOTSET) если args.udp: udp_proxy(args.src, args.dst) Элиф args.tcp: tcp_proxy(args.src, args.dst) # конец функции main если __name__ == '__main__': основной()

Однако, когда я запускаю команду testpyProxy.py —udp -d 192.168.2.13:7800 -s 192.168.2.2:7800, я никогда не получаю сообщение:

 2009-01-23 19:11:38,786 РАЗМЕР БУФЕРА ОТЛАДКИ : 32768
2009-01-23 19:11:38,786 DEBUG Запуск UDP-прокси...
2009-01-23 19:11:38,786 ОТЛАДКА Источник: 192.168.2.2:7800
2009-01-23 19:11:38,786 ОТЛАДКА Dst: 192.168.2.12:7800
2009-01-23 19:11:38,787 DEBUG Зацикливание прокси-сервера (чтобы остановить, нажмите Ctrl-Break). ..
 

Этот прокси-сервер Python работает на Centos 7 (192.168.2.2) машина со статистикой подключения порта ethernet из ifconfig:

 enp5s0f1: flags=4163 mtu 9000
        инет 192.168.2.2 сетевая маска 255.255.255.0 широковещательная рассылка 192.168.2.255
        inet6 fe80::21b:acff:fe02:af29 prefixlen 64 scopeid 0x20<ссылка>
эфир 00:1b:ac:02:af:29 txqueuelen 1000 (Ethernet) Пакеты RX 206136919 байт 494683048962 (460,7 ГиБ) Ошибки RX 0 отброшено 50795 переполнение 0 кадр 0 Пакеты TX 1018446 байт 564508158 (538,3 МБ) Ошибки передачи 0 отброшено 0 превышение пропускной способности 0 несущей 0 коллизий 0

Будем признательны за любую помощь.

ОБНОВЛЕНИЕ:

Я упростил код, который я запускаю, благодаря предложению от tdelaney. На стороне сервера (машина 192.168.2.2) я запускаю следующий код:

 #! /USR/бен/python3
импортный сокет
BUFFER_SIZE = 2 ** 9 # 1024.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *