Как правильно говорить розетка


Розетка или разетка - как правильно пишется слово

Определение и разбор слова

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

Давайте с этим разберёмся.

Существует два варианта правописания анализируемого слова:

  • “розетка”, где в первом слоге пишется буква “о”,
  • “разетка”, где в первом слове пишется буква “а”.

Как правильно пишется: “розетка” или “разетка”?

Согласно орфографической норме русского языка правильным является первый вариант:

розетка

Почему пишем букву “о”?

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

Отметим, что “розетка” происходит от немецкого слова “Rosette”, которое означает “розочка”. Таким образом, зная этимологию данного слова, будет проще запомнить его правописание.

Примеры для закрепления

  • Эта розетка не подходит под мой интерьер.
  • Купленная розетка была плохого качества.
  • Хрустальная розетка гармонично смотрелась с вареньем.

Как работают веб-сокеты? - Кевин Сукочефф

WebSocket - это постоянное соединение между клиентом и сервером. WebSockets обеспечивает двунаправленный полнодуплексный канал связи. который работает через HTTP через одно соединение сокета TCP / IP. На своем core протокол WebSocket упрощает передачу сообщений между клиентом и сервер. Эта статья представляет собой введение в WebSocket. протокол, в том числе проблемы, которые решают WebSockets, и обзор того, как WebSockets описываются на уровне протокола.

Почему именно WebSocket?

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

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

Обзор протокола

Протокол состоит из открывающего рукопожатия, за которым следует базовое сообщение. кадрирование, наложенное на TCP.

- RFC 6455 - Протокол WebSocket

WebSockets начинают свою жизнь как стандартный HTTP-запрос и ответ. Внутри этого цепочка ответов на запросы, клиент просит открыть соединение WebSocket, и сервер отвечает (если может). Если это первоначальное рукопожатие успешно, клиент и сервер согласились использовать существующий TCP / IP соединение, которое было установлено для HTTP-запроса как WebSocket подключение.Теперь данные могут передаваться через это соединение с использованием базового фреймового протокол сообщений. Как только обе стороны признают, что WebSocket соединение должно быть закрыто, TCP соединение разорвано.

Установление соединения WebSocket - Открытое рукопожатие WebSocket

WebSockets не используют схему http: // или https: // (потому что они не следовать протоколу HTTP). Вместо этого URI WebSocket используют новую схему ws: (или wss: для безопасного WebSocket).Остальная часть URI - это то же, что и HTTP URI: хост, порт, путь и любые параметры запроса.

  "ws:" "//" хост [":" порт] путь ["?" запрос] "wss:" "//" хост [":" порт] путь ["?" запрос]  

Соединения WebSocket могут быть установлены только для URI, следующих за этим схема. То есть, если вы видите URI со схемой ws: // (или wss: // ), тогда и клиент, и сервер ДОЛЖНЫ следовать соединению WebSocket. протокол в соответствии со спецификацией WebSocket.

подключений WebSocket установлено при обновлении пары HTTP-запрос / ответ. Клиент, который поддерживает WebSockets и хочет установить соединение, отправит HTTP запрос, который включает несколько обязательных заголовков:

  • Подключение: обновление
    • Заголовок Connection обычно определяет, сетевое соединение остается открытым после текущей транзакции отделка. Обычное значение для этого заголовка - keep-alive , чтобы убедитесь, что соединение является постоянным, чтобы разрешить последующие запросы на тот же сервер.Во время рукопожатия открытия WebSocket мы установили заголовок до Обновите , сигнализируя, что мы хотим сохранить соединение жив, и использовать его для запросов, отличных от HTTP.
  • Обновление: websocket
    • Заголовок Upgrade используется клиентами для запроса сервера на переключение к одному из перечисленных протоколов в порядке убывания предпочтения. Мы укажите здесь websocket , чтобы указать, что клиент хочет установить соединение WebSocket.
  • Sec-WebSocket-ключ: q4xkcO32u266gldTuKaSOw ==
    • Sec-WebSocket-Key - одноразовое случайное значение (nonce) генерируется клиентом.Значение представляет собой случайно выбранное 16-байтовое значение, имеющее был закодирован base64.
  • Sec-WebSocket-Версия: 13
    • Единственная допустимая версия протокола WebSocket - 13. Любая другая версия, указанная в этом заголовке, недействительна.

Вместе эти заголовки приведут к HTTP-запросу GET от клиент к URI ws: // , как в следующем примере:

  ПОЛУЧИТЬ ws: //example.com: 8181 / HTTP / 1.1 Хост: localhost: 8181 Подключение: Обновление Прагма: без кеширования Cache-Control: без кеша Обновление: websocket Sec-WebSocket-Версия: 13 Sec-WebSocket-ключ: q4xkcO32u266gldTuKaSOw ==  

Когда клиент отправляет начальный запрос на открытие соединения WebSocket, он ждет ответа от сервера.Ответ должен иметь код ответа HTTP 101 Switching Protocols . Ответ HTTP 101 Switching Protocols указывает, что сервер переключается на протокол, который клиент запрошен в заголовке запроса Upgrade . Кроме того, сервер должен включить заголовки HTTP, подтверждающие, что соединение было успешно улучшено:

  HTTP / 1.1 101 Протоколы коммутации Обновление: websocket Подключение: Обновление Sec-WebSocket-Accept: fA9dggdnMPU79lJgAE3W4TRnyDM =  
  • Подключение: обновление
    • Подтверждает, что соединение было обновлено.
  • Обновление: websocket
    • Подтверждает, что соединение было обновлено.
  • Sec-WebSocket-Accept : fA9dggdnMPU79lJgAE3W4TRnyDM = `
    • Sec-WebSocket-Accept имеет кодировку base64, хешированное значение SHA-1. Вы сгенерировать это значение путем объединения клиентов Sec-WebSocket-Key nonce и статическое значение 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 определено в RFC 6455. Хотя Sec-WebSocket-Key и Sec-WebSocket-Accept кажутся сложными, они существуют, так что оба клиент и сервер могут знать, что их коллега поддерживает WebSockets.Поскольку WebSocket повторно использует HTTP-соединение, там являются потенциальными проблемами безопасности, если любая из сторон интерпретирует WebSocket данные как HTTP-запрос.

После того, как клиент получит ответ сервера, соединение WebSocket открыть, чтобы начать передачу данных.

Протокол WebSocket

WebSocket - это протокол с фреймами , что означает, что фрагмент данных (сообщение) делится на несколько дискретных частей, размер которых закодировано в кадре.Кадр включает тип кадра, длину полезной нагрузки, и часть данных. Обзор фрейма дан в RFC. 6455 и воспроизведено Вот.

  0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + - + - + - + - + ------- + - + ------------- + ----------------- -------------- + | F | R | R | R | код операции | M | Длина полезной нагрузки | Увеличенная длина полезной нагрузки | | I | S | S | S | (4) | A | (7) | (16/64) | | N | V | V | V | | S | | (если полезная нагрузка len == 126/127) | | | 1 | 2 | 3 | | K | | | + - + - + - + - + ------- + - + ------------- + - - - - - - - - - - - - - - - + | Увеличенная длина полезной нагрузки продолжается, если полезная нагрузка len == 127 | + - - - - - - - - - - - - - - - + ------------------------------- + | | Маскирующий ключ, если МАСКА установлена ​​в 1 | + ------------------------------- + ----------------- -------------- + | Маскирующий ключ (продолжение) | Данные полезной нагрузки | + -------------------------------- - - - - - - - - - - - - - - - - + : Данные полезной нагрузки продолжение...: + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Данные полезной нагрузки продолжение ... | + ------------------------------------------------- -------------- +  

Я не буду здесь останавливаться на всех деталях протокола кадров. Обратитесь к RFC 6455 для получения полной информации. Скорее, Я расскажу о самых важных моментах, чтобы мы могли понять протокола WebSocket.

Ребро-бит

Первый бит заголовка WebSocket - это бит Fin.Этот бит устанавливается, если этот фрейм - последние данные для завершения этого сообщения.

Биты RSV1, RSV2, RSV3

Эти биты зарезервированы для использования в будущем.

код операции

У каждого кадра есть код операции, который определяет, как интерпретировать данные полезной нагрузки.

Значение кода операции Описание
0x00 Этот кадр продолжает полезную нагрузку из предыдущего кадра.
0x01 Обозначает текстовый фрейм.Текстовые фреймы декодируются сервером в кодировке UTF-8.
0x02 Обозначает двоичный фрейм. Двоичные фреймы доставляются сервером без изменений.
0x03-0x07 Зарезервировано для использования в будущем.
0x08 Обозначает, что клиент хочет закрыть соединение.
0x09 Фрейм ping. Служит механизмом подтверждения связи, гарантирующим, что соединение все еще живо. Получатель должен ответить понгом.
0x0a Рамка для понга. Служит механизмом подтверждения связи, гарантирующим, что соединение все еще живо. Получатель должен ответить фреймом ping.
0x0b-0x0f Зарезервировано для использования в будущем.
Маска

Установка этого бита в 1 включает маскирование . WebSockets требует, чтобы все полезная нагрузка обфусцирована с использованием случайного ключа (маски), выбранного клиентом. Ключ маскировки объединяется с данными полезной нагрузки с помощью операции XOR. перед отправкой данных в полезную нагрузку.Эта маскировка предотвращает появление кешей. неверная интерпретация фреймов WebSocket как кэшируемых данных. Почему мы должны предотвращать кеширование данных WebSocket? Безопасность.

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

Длина полезной нагрузки

Поле Payload len и Extended payload length поле используются для кодировать общую длину данных полезной нагрузки для этого кадра. Если полезная нагрузка данные небольшие (менее 126 байт), длина кодируется в поле Payload len . По мере роста данных полезной нагрузки мы используем дополнительные поля для закодировать длину полезной нагрузки.

Маскирующий ключ

Как обсуждалось с битом MASK , все кадры, отправленные от клиента к серверы маскируются 32-битным значением, содержащимся в кадре. Это поле присутствует, если бит маски установлен в 1, и отсутствует, если бит маски установлен на 0.

Данные полезной нагрузки

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

Закрытие соединения WebSocket - рукопожатие закрытия WebSocket

Чтобы закрыть соединение WebSocket, отправляется закрывающий кадр (код операции 0x08 ). Помимо кода операции, закрывающий кадр может содержать тело, которое указывает причину закрытия. Если одна из сторон соединения получает закрывающий кадр, он должен отправить закрытый кадр в ответ, и больше никаких данных должны быть отправлены через соединение. После получения кадра закрытия обеими сторонами разрывается TCP-соединение.Сервер всегда инициирует закрытие TCP-соединения.

Дополнительные ссылки

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

См. Также
.Программирование сокетов

на Python (Руководство) - Real Python

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

В этом руководстве есть три различных итерации построения сервера и клиента сокетов с помощью Python:

  1. Мы начнем обучение с рассмотрения простого сервера и клиента сокета.
  2. После того, как вы познакомились с API и принципами работы в этом начальном примере, мы рассмотрим улучшенную версию, которая обрабатывает несколько подключений одновременно.
  3. Наконец, мы перейдем к созданию примера сервера и клиента, которые функционируют как полноценное приложение для сокетов, со своим собственным настраиваемым заголовком и содержимым.

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

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

Сети и розетки - большие предметы. О них написаны буквально тома. Если вы новичок в сокетах или сетях, это совершенно нормально, если вы чувствуете себя перегруженным всеми терминами и частями. Я знаю, что сделал!

Но не расстраивайтесь.Я написал для вас это руководство. Как и в случае с Python, мы можем учиться понемногу за раз. Воспользуйтесь функцией закладок в браузере и вернитесь, когда будете готовы к следующему разделу.

Приступим!

Фон

Розетки имеют долгую историю. Их использование началось с ARPANET в 1971 году, а позже стало API в операционной системе Berkeley Software Distribution (BSD), выпущенной в 1983 году, под названием Berkeley Sockets.

Когда в 1990-х годах появился Интернет, вместе с World Wide Web росло и сетевое программирование.Веб-серверы и браузеры были не единственными приложениями, использующими преимущества новых подключенных сетей и сокетов. Широкое распространение получили клиент-серверные приложения всех типов и размеров.

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

Наиболее распространенным типом приложений сокетов являются приложения клиент-сервер, в которых одна сторона выступает в роли сервера и ожидает соединений от клиентов.Это тип приложения, о котором я расскажу в этом руководстве. В частности, мы рассмотрим API сокетов для Интернет-сокетов, иногда называемых сокетами Беркли или BSD. Существуют также доменные сокеты Unix, которые могут использоваться только для связи между процессами на одном и том же хосте.

Обзор API сокетов

Модуль сокетов

Python предоставляет интерфейс к API сокетов Беркли. Это модуль, который мы будем использовать и обсуждать в этом руководстве.

Основные функции и методы API сокетов в этом модуле:

  • розетка ()
  • привязка ()
  • слушать ()
  • принять ()
  • подключение ()
  • connect_ex ()
  • отправить ()
  • прием ()
  • закрыть ()

Python предоставляет удобный и согласованный API, который напрямую отображается на эти системные вызовы, их аналоги на C.В следующем разделе мы рассмотрим, как они используются вместе.

В составе стандартной библиотеки Python также есть классы, упрощающие использование этих низкоуровневых функций сокетов. Хотя это не рассматривается в этом руководстве, см. Модуль socketserver, платформу для сетевых серверов. Также доступно множество модулей, реализующих Интернет-протоколы более высокого уровня, такие как HTTP и SMTP. Для обзора см. Интернет-протоколы и поддержка.

Сокеты TCP

Как

.HOWTO по программированию сокетов

- документация Python 3.9.0

Автор

Гордон Макмиллан

Аннотация

Розетки используются почти везде, но являются одними из самых неправильно понятые технологии вокруг. Это обзор розеток на 10 000 футов. На самом деле это не учебник - вам еще нужно поработать, чтобы что-то получить оперативный. Он не касается тонких моментов (а их очень много), но Я надеюсь, что это даст вам достаточно знаний, чтобы начать их прилично использовать.

Розетки

Я буду говорить только о сокетах INET (то есть IPv4), но они составляют не менее 99% используемые розетки. И я буду говорить только о сокетах STREAM (т. Е. TCP) - если только вы знать, что вы делаете (в этом случае этот HOWTO не для вас!), вы получите лучшее поведение и производительность от сокета STREAM, чем что-либо еще. Я буду попытаться раскрыть тайну того, что такое сокет, а также дать несколько советов о том, как работа с блокирующими и неблокирующими розетками.Но я начну с разговора о блокировка розеток. Вам нужно знать, как они работают, прежде чем начинать неблокирующие розетки.

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

История

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

Они были изобретены в Беркли как часть разновидности BSD Unix. Они распространяются как лесной пожар с Интернетом. Не зря - комбинация розеток. с INET невероятно легко общаться с произвольными машинами по всему миру (по крайней мере, по сравнению с другими схемами).

Создание сокета

Грубо говоря, когда вы нажимали на ссылку, которая привела вас на эту страницу, ваш браузер сделал что-то вроде следующего:

 # создать INET, STREAMing сокет s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) # теперь подключаемся к веб-серверу через порт 80 - обычный http порт s.connect (("www.python.org", 80)) 

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

То, что происходит на веб-сервере, немного сложнее. Во-первых, веб-сервер создает «серверный сокет»:

 # создать INET, STREAMing сокет serversocket = socket.socket (socket.AF_INET, socket.SOCK_STREAM) # привязываем сокет к общедоступному хосту и известному порту serversocket.bind ((socket.gethostname (), 80)) # стать серверным сокетом серверный сокет.слушать (5) 

Следует отметить пару моментов: мы использовали socket.gethostname () , чтобы сокет будет видно внешнему миру. Если бы мы использовали s.bind (('localhost', 80)) или s.bind (('127.0.0.1', 80)) у нас все равно будет сокет «сервер», но тот, который был виден только внутри той же машины. s.bind (('', 80)) указывает, что сокет доступен по любому адресу, с которым встречается машина имеют.

Второе замечание: порты с небольшим номером обычно зарезервированы для «хорошо известных» сервисы (HTTP, SNMP и т. д.).Если вы играете, используйте хорошее большое число (4 цифры).

Наконец, аргумент listen сообщает библиотеке сокетов, что мы хотим, чтобы поставьте в очередь до 5 запросов на соединение (нормальный максимум), прежде чем отказывать извне соединения. Если остальная часть кода написана правильно, этого должно быть достаточно.

Теперь, когда у нас есть «серверный» сокет, прослушивающий порт 80, мы можем ввести основной цикл веб-сервера:

, пока True: # принимать подключения извне (клиентский сокет, адрес) = серверный сокет.accept () # теперь что-нибудь сделаем с клиентским сокетом # в данном случае мы представим, что это многопоточный сервер ct = client_thread (клиентский сокет) ct.run () 

На самом деле существует 3 основных способа работы этого цикла - отправка поток для обработки clientocket , создайте новый процесс для обработки clientocket , или реструктурируйте это приложение для использования неблокирующих сокетов, и мультиплексирование между нашим «серверным» сокетом и любым активным клиентским сокетом с использованием выберите .Подробнее об этом позже. Сейчас важно понять, это: это все «серверный» сокет. Он не отправляет никаких данных. Это не получать любые данные. Он просто производит «клиентские» сокеты. Каждому клиентскому сокету соответствует создается в ответ на , другой «клиентский» сокет, выполняющий connect () с хост и порт, к которым мы привязаны. Как только мы создали этот клиентский сокет , мы вернитесь к прослушиванию для получения дополнительных подключений. Два «клиента» могут свободно общаться в чате. вверх - они используют какой-то динамически выделенный порт, который будет переработан, когда разговор заканчивается.

МПК

Если вам нужен быстрый IPC между двумя процессами на одной машине, вам следует изучить каналы или разделяемая память. Если вы решили использовать сокеты AF_INET, привяжите Сокет «server» на «localhost» . На большинстве платформ это займет сократить несколько слоев сетевого кода и работать немного быстрее.

См. Также

Многопроцессорная модель интегрирует межплатформенные IPC в более высокий уровень API.

Использование розетки

Первое, на что следует обратить внимание, это то, что «клиентский» сокет веб-браузера и Интернет серверные «клиентские» сокеты такие же звери.То есть это «одноранговый» разговор. Или, другими словами, в качестве дизайнера вам придется решить, каковы правила этикета для разговора . Обычно connect ing socket начинает диалог, отправляя запрос, или возможно знак. Но это дизайнерское решение, а не розетки.

Теперь есть два набора глаголов, которые можно использовать для общения. Вы можете использовать отправить и recv , или вы можете превратить свой клиентский сокет в файлового зверя и используйте для чтения и для записи .Именно так Java представляет свои сокеты. Я не собираюсь здесь говорить об этом, но хочу предупредить, что вам нужно использовать заподлицо на розетки. Это буферизованные «файлы», и распространенной ошибкой является напишите что-нибудь, а затем прочтите для ответа. Без промывки дюймов там вы можете ждать ответа вечно, потому что запрос все еще может быть в ваш выходной буфер.

Теперь мы подошли к главному камню преткновения розеток - send и recv работают. в сетевых буферах.Они не обязательно обрабатывают все передаваемые вами байты их (или ожидайте от них), потому что их основное внимание уделяется работе с сетью буферы. Как правило, они возвращаются, когда связанные сетевые буферы были заполнены ( отправить ) или опустошены ( recv ). Затем они сообщают вам, сколько байтов они обработано. - это ваша ответственность - позвонить им еще раз, пока ваше сообщение не будет полностью разобрались.

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

Протокол, подобный HTTP, использует сокет только для одной передачи. Клиент отправляет запрос, затем читает ответ. Это оно. Сокет отбрасывается. Это значит, что клиент может определить конец ответа, получив 0 байтов.

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

Если вы не хотите разрывать соединение, самым простым решением является фиксированный длина сообщения:

 класс MySocket: "" "только демонстрационный класс - закодировано для ясности, а не эффективности "" " def __init __ (self, sock = None): если носок None: self.sock = socket.socket ( сокет.AF_IN 
.HOWTO по программированию сокетов

- документация Python 2.7.18

Автор

Гордон Макмиллан

Аннотация

Розетки используются почти везде, но являются одними из самых неправильно понятые технологии вокруг. Это обзор розеток на 10 000 футов. На самом деле это не учебник - вам еще нужно поработать, чтобы что-то получить оперативный. Он не касается тонких моментов (а их очень много), но Я надеюсь, что это даст вам достаточно знаний, чтобы начать их прилично использовать.

Розетки

Я буду говорить только о сокетах INET, но они составляют не менее 99% используемые розетки. И я буду говорить только о розетках STREAM - если только вы знать, что вы делаете (в этом случае этот HOWTO не для вас!), вы получите лучшее поведение и производительность от сокета STREAM, чем что-либо еще. Я буду попытаться раскрыть тайну того, что такое сокет, а также дать несколько советов о том, как работа с блокирующими и неблокирующими розетками. Но я начну с разговора о блокировка розеток.Вам нужно знать, как они работают, прежде чем начинать неблокирующие розетки.

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

История

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

Они были изобретены в Беркли как часть разновидности BSD Unix. Они распространяются как лесной пожар с Интернетом. Не зря - комбинация розеток. с INET невероятно легко общаться с произвольными машинами по всему миру (по крайней мере, по сравнению с другими схемами).

Создание сокета

Грубо говоря, когда вы нажимали на ссылку, которая привела вас на эту страницу, ваш браузер сделал что-то вроде следующего:

 # создать сокет INET, STREAMing s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM) # теперь подключитесь к веб-серверу через порт 80 # - нормальный http порт s.connect (("www.mcmillan-inc.com", 80)) 

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

То, что происходит на веб-сервере, немного сложнее. Во-первых, веб-сервер создает «серверный сокет»:

 # создать сокет INET, STREAMing serversocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM) # привязываем сокет к общедоступному хосту, # и известный порт serversocket.bind ((socket.gethostname (), 80)) # стать серверным сокетом serversocket.listen (5) 

Следует отметить пару моментов: мы использовали socket.gethostname () , чтобы сокет будет видно внешнему миру. Если бы мы использовали s.bind (('localhost', 80)) или s.bind (('127.0.0.1', 80)) у нас все равно будет сокет «сервер», но тот, который был виден только внутри той же машины. s.bind (('', 80)) указывает, что сокет доступен по любому адресу, с которым встречается машина имеют.

Второе замечание: порты с небольшим номером обычно зарезервированы для «хорошо известных» сервисы (HTTP, SNMP и т. д.). Если вы играете, используйте хорошее большое число (4 цифры).

Наконец, аргумент listen сообщает библиотеке сокетов, что мы хотим, чтобы поставьте в очередь до 5 запросов на соединение (нормальный максимум), прежде чем отказывать извне соединения. Если остальная часть кода написана правильно, этого должно быть достаточно.

Теперь, когда у нас есть «серверный» сокет, прослушивающий порт 80, мы можем ввести основной цикл веб-сервера:

, а 1: # принимать подключения извне (клиентский сокет, адрес) = серверный сокет.accept () # теперь сделайте что-нибудь с клиентским сокетом # в данном случае мы представим, что это многопоточный сервер ct = client_thread (клиентский сокет) ct.run () 

На самом деле существует 3 основных способа работы этого цикла - отправка поток для обработки clientocket , создайте новый процесс для обработки clientocket , или реструктурируйте это приложение для использования неблокирующих сокетов, и мультиплексирование между нашим «серверным» сокетом и любым активным клиентским сокетом с использованием выберите .Подробнее об этом позже. Сейчас важно понять, это: это все «серверный» сокет. Он не отправляет никаких данных. Это не получать любые данные. Он просто производит «клиентские» сокеты. Каждому клиентскому сокету соответствует создается в ответ на , другой «клиентский» сокет, выполняющий connect () с хост и порт, к которым мы привязаны. Как только мы создали этот клиентский сокет , мы вернитесь к прослушиванию для получения дополнительных подключений. Два «клиента» могут свободно общаться в чате. вверх - они используют какой-то динамически выделенный порт, который будет переработан, когда разговор заканчивается.

МПК

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

Если вы все же решите использовать сокеты, привяжите «серверный» сокет к 'localhost' . На на большинстве платформ это позволит сократить несколько уровней сети. код и быть немного быстрее.

Использование розетки

Первое, на что следует обратить внимание, это то, что «клиентский» сокет веб-браузера и Интернет серверные «клиентские» сокеты такие же звери.То есть это «одноранговый» разговор. Или, другими словами, в качестве дизайнера вам придется решить, каковы правила этикета для разговора . Обычно connect ing socket начинает диалог, отправляя запрос, или возможно знак. Но это дизайнерское решение, а не розетки.

Теперь есть два набора глаголов, которые можно использовать для общения. Вы можете использовать отправить и recv , или вы можете превратить свой клиентский сокет в файлового зверя и используйте для чтения и для записи .Именно так Java представляет свои сокеты. Я не собираюсь здесь говорить об этом, но хочу предупредить, что вам нужно использовать заподлицо на розетки. Это буферизованные «файлы», и распространенной ошибкой является напишите что-нибудь, а затем прочтите для ответа. Без промывки дюймов там вы можете ждать ответа вечно, потому что запрос все еще может быть в ваш выходной буфер.

Теперь мы подошли к главному камню преткновения розеток - send и recv работают. в сетевых буферах.Они не обязательно обрабатывают все передаваемые вами байты их (или ожидайте от них), потому что их основное внимание уделяется работе с сетью буферы. Как правило, они возвращаются, когда связанные сетевые буферы были заполнены ( отправить ) или опустошены ( recv ). Затем они сообщают вам, сколько байтов они обработано. - это ваша ответственность - позвонить им еще раз, пока ваше сообщение не будет полностью разобрались.

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

Протокол, подобный HTTP, использует сокет только для одной передачи. Клиент отправляет запрос, затем читает ответ. Это оно. Сокет отбрасывается. Это значит, что клиент может определить конец ответа, получив 0 байтов.

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

Если вы не хотите разрывать соединение, самым простым решением является фиксированный длина сообщения:

 класс mysocket: '' 'только демонстрационный класс - закодировано для ясности, а не эффективности '' ' def __init __ (self, sock = None): если носок None: self.sock = socket.socket ( socket.AF_INET, socket.SOCK_STREAM) еще: self.sock = носок 
.

Смотрите также