Что такое компьютерный порт и для чего он используется?

Что такое порт?

Итак, что такое порт? Мы можем называть эти порты гнездами или розетками, но правильным термином является порт. Основная функция этих портов состоит в том, чтобы позволить одному оборудованию подключаться к другому, чтобы они могли общаться друг с другом. С технической точки зрения это порты ввода/вывода (I/O или IO). Количество портов, которые может иметь устройство, ограничено доступным физическим пространством.

Есть две группы портов — последовательный и параллельный. Группировка основана на том, как порт разрешает связь.

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

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

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

Допустим, мы отправляем сообщение двум людям, например, «Привет», поездом и грузовиком. Мы отправляем его одному человеку на поезде, а другому — на грузовике. Каждое приветственное письмо написано на передней части грузовика и на передней части вагона.

Человек, ожидающий поезда, серийный метод, увидит H на двигателе, затем E на следующем грузовом вагоне, затем первый L на следующем вагоне, затем второй L на следующем вагоне и O на финальная машина.

Человек, ожидающий грузовики на 5-полосной трассе, увидит, как все грузовики прибывают одновременно, бок о бок, и излагает привет.

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

Протокол управления передачей (TCP) использует набор каналов связи, называемых портами, для управления системным обменом сообщениями между несколькими различными приложениями, работающими на одном физическом устройстве. В отличие от физических портов на компьютерах, таких как USB-порты или Ethernet-порты, TCP-порты являются виртуально программируемыми записями, пронумерованными от 0 до 65535.

Большинство портов TCP являются каналами общего назначения, которые могут вызываться при необходимости, но в остальном бездействуют. Однако некоторые порты с меньшими номерами предназначены для определенных приложений. Хотя многие TCP-порты принадлежат приложениям, которые больше не существуют, некоторые из них очень популярны.

TCP порт 0

TCP фактически не использует порт 0 для сетевого взаимодействия, но этот порт хорошо известен сетевым программистам. Программы сокетов TCP используют порт 0 по соглашению, чтобы запросить доступный порт, который будет выбран и выделен операционной системой. Это избавляет программиста от необходимости выбирать («жесткий код») номер порта, который может не сработать в данной ситуации.

TCP-порты 20 и 21

FTP-серверы используют TCP-порт 21 для управления своей стороной сеансов FTP. Сервер прослушивает команды FTP, поступающие на этот порт, и отвечает соответствующим образом. В активном режиме FTP сервер дополнительно использует порт 20 для инициирования передачи данных обратно клиенту FTP.

TCP-порт 22

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

TCP-порт 23

Порт 23 управляет telnet , текстовой системой для входа в удаленные системы. Хотя современные подходы к удаленному доступу основаны на Secure Shell на порте 22, порт 23 остается зарезервированным для более старого и менее безопасного приложения telnet.

TCP-порты 25, 110 и 143

На принимающей стороне порт 110 управляет протоколом почтовой связи версии 3, а порт 143 выделен для протокола доступа к почте через Интернет. POP3 и IMAP контролируют поток электронной почты с сервера вашего провайдера на ваш почтовый ящик.

Безопасные версии SMTP и IMAP различаются в зависимости от конфигурации, но порты 465 и 587 являются общими.

UDP порты 67 и 68

Серверы протокола динамической конфигурации хоста используют UDP-порт 67 для прослушивания запросов, в то время как клиенты DHCP обмениваются данными через UDP-порт 68.

TCP-порты 80 и 443

Возможно, самый известный порт в Интернете – TCP-порт 80 – это значение по умолчанию, которое веб-серверы HyperText Transfer Protocol прослушивают для запросов веб-браузера.

Порт 443 по умолчанию для безопасного HTTP.

UDP-порты 161 и 162

По умолчанию простой протокол управления сетью использует UDP-порт 161 для отправки и получения запросов в управляемой сети. Он использует UDP-порт 162 по умолчанию для получения прерываний SNMP от управляемых устройств.

TCP-порт 194

Несмотря на то, что такие инструменты, как приложения для обмена сообщениями на смартфонах, такие как Slack и Microsoft Teams, стали использовать Internet Relay Chat, IRC по-прежнему пользуется популярностью среди людей по всему миру. По умолчанию IRC использует порт 194.

Порты выше 1023

Номера портов TCP и UDP между 1024 и 49151 называются зарегистрированными портами . Управление по присвоению номеров в Интернете ведет список услуг, использующих эти порты, чтобы минимизировать конфликты при использовании.

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

Порт[править]

Сетевой порт — это сетевой ресурс, отображаемый в виде числа (1-65535), которое определяет назначение входящих или исходящих сетевых потоков данных на заданном устройстве.

Если прибегнуть к аналогии, IP-адрес — это адрес общежития с вахтёром, а порт — номер комнаты в этом общежитии или фамилия ее жильца.

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

Например, почтовое письмо (пакет данных) имеет информацию об отправителе (порт) и информацию о получателе (фамилия или номер комнаты по конкретному адресу).

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

Использование портов позволяет независимо использовать TCP протокол («почтовые услуги») сразу многим приложениям на одном и том же компьютере (общежитии).

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

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

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

Таким образом, сервер:

  • слушает на определённом порту, заранее известном клиенту
  • занимает этот порт всё время, пока не завершит работу
  • об IP-адресе и номере порта клиента узнаёт из приглашения, посланного клиентом

Клиент:

  • заранее знает IP-адрес и порт сервера
  • выбирает у себя произвольный порт, который освобождает после окончания соединения
  • посылает приглашение к соединению

Этап 1: Инициализация сокетных интерфейсов Win32API

Прежде чем непосредственно создать объект сокет, необходимо «запустить» программные интерфейсы для работы с ними. Под Windows это делается в два шага следующим образом:

  • Нужно определить с какой версией сокетов мы работаем (какую версию понимает наша ОС) и

  • Запустить программный интерфейс сокетов в Win32API. Ну либо расстроить пользователя тем, что ему не удастся поработать с сокетами до обновления системных библиотек

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

Второй шаг – непосредственный вызов функции запуска сокетов с помощью . Упрощённый прототип данной функции выглядит так:

Первый аргумент функции – указание диапазона версий реализации сокетов, которые мы хотим использовать и которые должны быть типа . Этот тип данных является внутренним типом и представляет собой двухбайтовое слово (аналог в С++: ). Функция просит вас передать ей именно , а она уже разложит значение переменной внутри по следующему алгоритму: функция считает, что в старшем байте слова указана минимальная версия реализации сокетов, которую хочет использовать пользователь, а в младшем – максимальная. По состоянию на дату написания этой статьи (октябрь 2021 г.) актуальная версия реализации сокетов в Windows – 2. Соответственно, желательно передать и в старшем, и в младшем байте число 2. Для того, чтобы создать такую переменную типа и передать в её старший и младший байты число 2, можно воспользоваться функцией .

Можно немного повыёживаться и вспомнить (или полистать MSDN), что функция строит слово по правилу .Нетрудно посчитать, что при x=y=2 значение функции в десятичном виде будет . Можешь смело передать в это значение, и всё будет работать.

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

в случае успеха возвращает 0, а в случае каких-то проблем возвращает код ошибки, который можно расшифровать последующим вызовом функции .

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

Используем для этого переменную типа .

Также важно после работы приложения обязательно закрыть использовавшиеся сокеты с помощью функции и деинициализировать сокеты Win32API через вызов метода. Итого код Этапа 1 следующий:

Итого код Этапа 1 следующий:

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

Этап 3: Привязка сокета к паре IP-адрес/Порт

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

Такое назначение делается с помощью функции , имеющей следующий прототип:

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

Тут надо немножно притормозить и разобраться в том, что за такая структура типа передается вторым аргументом в функцию . Она очень важна, но достаточно запутанная.

Итак, если посмотреть в её внутренности, то выглядят они очень просто: в ней всего два поля – (1) первое поле хранит семейство адресов, с которыми мы уже встречались выше при инициализации сокета, а (2) второе поле хранит некие упакованные последовательно и упорядоченные данные в размере 14-ти байт. Бессмысленно разбираться детально как именно эти данные упакованы, достаточно лишь понимать, что в этих 14-ти байтах указан и адрес, и порт, а также дополнительная служебная информация для других системных функций .

Но как же явно указать адрес и порт для привязки сокета? Для этого нужно воспользоваться другой структурой, родственной , которая легко приводится к этому типу — структурой типа .

В ней уже более понятные пользователю поля, а именно:

  • Семейство адресов — опять оно ()

  • Порт ()

  • Вложенная структура типа , в которой будет храниться сам сетевой адрес ()

  • Технический массив на 8 байт ()

При приведении типа к нужному нам типу для использования в функции поля Порт (2 байта), Сетевой адрес (4 байта) и Технический массив (8 байт) как раз в сумме дают нам 14 байт, помещающихся в 14 байт, находящихся во втором поле структуры . Первые поля у указанных типов совпадают – это семейство адресов сокетов (указываем ). Из этого видно, что структуры данных типа и тождественны, содержат одну и ту же информацию, но в разной форме для разных целей.

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

  1. Создание структуры типа :

  2. Заполнение полей созданной структуры

  • порт всегда указывается через вызов функции , которая переупаковывает привычное цифровое значение порта типа в побайтовый порядок понятный для протокола TCP/IP (протоколом установлен порядок указания портов от старшего к младшему байту или «big-endian»).

  • Далее нам надо указать сетевой адрес для сокета. Тип этого поля – структура типа , которая по своей сути представляет просто особый «удобный» системным функциям вид обычного строчного IPv4 адреса. Таким образом, чтобы указать этому полю обычный IPv4 адрес, его нужно сначала преобразовать в особый числовой вид и поместить в структуру типа .

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

    В случае ошибки функция возвращает значение меньше 0.

    Соответственно, если мы хотим привязать сокет к локальному серверу, то наш код по преобразованию IPv4 адреса будет выглядеть так:

    Результат перевода IP-адреса содержится в структуре И далее мы передаем уже в нашу переменную типа значение преобразованного адреса:

Вся нужная информация для привязки сокета теперь у нас есть, и она хранится в структуре . Можно смело вызывать функцию , не забыв при этом привести из типа в требуемый функции. Тогда итоговый код Этапа 3 (слава богу закончили) выглядит так:

Этап 6: Передача данных между Клиентом и Сервером

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

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

Рассмотрим прототипы функций и :

Флаги в большинстве случаев игнорируются – передается значение 0.

Функции возвращают количество переданных/полученных по факту байт.

Как видно из прототипов, по своей структуре и параметрам эти функции совершенно одинаковые

Что важно знать:

и та, и другая функции не гарантируют целостности отправленной/полученной информации

Это значит, что при реализации прикладных задач по взаимодействию Клиента и Сервера с их использованием требуется принимать дополнительные меры для контроля того, что все посланные байты действительно посланы и, что еще более важно, получены в том же объеме на другой стороне
предельно внимательно надо относиться к параметру «размер буфера». Он должен в точности равняться реальному количеству передаваемых байт

Если он будет отличаться, то есть риск потери части информации или «замусориванию» отправляемой порции данных, что ведет к автоматической поломке данных в процессе отправки/приёма. И совсем замечательно будет, если размер буфера по итогу работы функции равен возвращаемому значению функции – размеру принятых/отправленных байт.

В качестве буфера рекомендую использовать не классические массивы в С-стиле, а стандартный класс С++ <vector> типа char, т.к. он показал себя как более надежный и гибкий механизм при передаче данных, в особенности при передаче текстовых строк, где важен терминальный символ и «чистота» передаваемого массива.

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

Процесс непрерывного перехода от send() к recv() и обратно реализуется через бесконечный цикл, из которого совершается выход по вводу особой комбинации клавиш. Пример блока кода для Серверной части:

Пришло время показать итоговый рабочий код для Сервера и Клиента. Чтобы не загромождать и так большой текст дополнительным кодом, даю ссылки на код на GitHub:

Несколько важных финальных замечаний:

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

  • При тестировании примера также видно, что чат рабочий, но очень уж несовершенный. Наиболее проблемное место – невозможность отправить сообщение пока другая сторона не ответила на твоё предыдущее сообщение. Суть проблемы в том, что после отсылки сообщения сторона-отправитель вызывает функцию recv(), которая, как я писал выше, блокирует исполнение последующего кода, в том числе блокирует вызов прерываний для осуществления ввода. Это приводит к тому, что набирать сообщение и что-то отправлять невозможно до тех пор, пока процесс не получит ответ от другой стороны, и вызов функции recv() не будет завершен. Благо введенная информация с клавиатуры не будет потеряна, а, накапливаясь в системном буфере ввода/вывода, будет выведена на экран как только блокировка со стороны recv() будет снята. Таким образом, мы реализовали так называемый прямой полудуплексный канал связи. Сделать его полностью дуплексным в голой сокетной архитектуре достаточно нетривиальная задача, частично решаемая за счет создания нескольких параллельно работающих потоков или нитей (threads) исполнения. Один поток будет принимать информацию, а второй – отправлять.

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

Mr_Dezz

Что такое маска адреса (подсеть)

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

Маска — это параметр, который сообщает программному обеспечению о том, сколько компьютеров объединено в данную группу (подсеть). Маска адреса имеет такую же структуру как и сам IP-адрес: это набор из четырех групп чисел, каждое из которых может быть в диапазоне от 0 до 255. При этом, чем меньше значение маски, тем больше компьютеров объединено в данную подсеть. Для сетей небольших компаний маска обычно имеет вид 255.255.255.x (например, 255.255.255.224). Маска сети присваивается компьютеру одновременно с IP-адресом. Так, например, сеть 192.168.0.0 с маской 255.255.255.0 может содержать в себе компьютеры с адресами от 192.168.0.1 до 192.168.254. А сеть 192.168.0.0 с маской 255.255.255.128 допускает адреса от 192.168.0.1 до 192.168.0.127. Думаю, смысл понятен. Как правило сети с небольшим возможным числом компьютеров используются провайдерами с целью экономии IP-адресов. Например, клиенту, может быть назначен адрес с маской 255.255.255.252. Такая подсеть содержит в себе только два компьютера.

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

Этап 5 (только для Сервера). Подтверждение подключения

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

 Функция возвращает номер дескриптора, под которым зарегистрирован сокет в ОС. Если произошла ошибка, то возвращается значение .

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

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

Выбор номера[править]

Порт — это просто любое условное число от 0 до 65535. Теоретически номер порта ни на что не влияет

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

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

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

  • Для системных и некоторых популярных программ выделены порты с номерами от 0 до 1023, называемые системными или общеизвестными.
  • Порты с номерами 1024 — 49151 называются пользовательскими или зарегистрированными.
  • Порты с номерами 49152 — 65535 называются динамическими, эфемерными или частными.

См. также: Список портов TCP и UDP

Проверка доступности[править]

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

Клиентомправить

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

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

Telnetправить

Для проверки доступности TCP-порта (а большинство прикладных протоколов используют TCP) достаточно попытаться установить с вашим сервером «сырое» TCP-соединение с помощью telnet.

  • В Windows XP: нажмите Пуск -> Выполнить (Win+R), затем в открывшемся окне наберите и нажмите «Ок».
  • В Windows Vista и Windows 7 необходимо установить соответствующий компонент: «Панель управления» — «Программы и компоненты» — «Включение или отключение компонентов Windows» — «Клиент Telnet». После перезагрузки компьютера нажмите Пуск -> Выполнить (Win+R), наберите и нажмите «Ок».

В появившемся окне командной строки наберите , введите через пробелы IP-адрес, затем номер порта и нажмите «Enter».

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

Сканеромправить

В сети есть специальные онлайн-сканеры портов.

Ваш IP-адрес сканер видит сам, а порт вы ему сообщаете, и он делает попытку установить к вашему серверу TCP-соединение. Статус порта Open означает, что ваш порт прослушивания доступен.

Другие сканеры:

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

Этот сканер позволяет проверить порт для любого IP-адреса:

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Работатека
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: