Sockets Python

Содержание
Введение
Пример
Пример с обработкой данных
gethostbyname()
Похожие статьи

Введение

Этот модуль обеспечивает доступ к интерфейсу сокета BSD. Он доступен во всех современных системах Unix , Windows , macOS и, возможно, на дополнительных платформах.

Про то, что такое TCP сокет и про сети в целом вы можете прочитать в статье «Компьютерные сети»

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

Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. Дополнительные сведения см. в разделе Платформы веб-сборки .

Интерфейс Python представляет собой простую транслитерацию системного вызова Unix и библиотечного интерфейса для сокетов в объектно-ориентированный стиль Python: функция socket() возвращает объект socket, методы которого реализуют различные системные вызовы сокетов. Типы параметров несколько более высокоуровневые, чем в интерфейсе C: как и в случае операций чтения() и записи() в файлах Python, распределение буфера при операциях приема происходит автоматически, а длина буфера неявно указывается при операциях отправки.

Официальная документация

Изображение баннера

Пример

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

Клиент от такого сервера ничего полезного не получит.

import socket import sys sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('', 10000) print(sys.stderr, 'starting up on %s port %s' % server_address) sock.bind(server_address) sock.listen(1) while True: print(sys.stderr, 'waiting for connection') connection, client_address = sock.accept() try: print(sys.stderr, 'connection from', client_address) while True: data = connection.recv(16) print(sys.stderr, 'received "%s"' % data) if data: print(sys.stderr, 'sending data back to the client') connection.sendall(data) else: print(sys.stderr, 'no more data from', client_address) break finally: connection.close()

Для этого сервера подойдёт самый простой клиент

import socket import sys # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect the socket to the port where the server is listening # server_address = ('localhost', 10000) server_address = ('192.168.56.113', 10000) print(sys.stderr, 'connecting to %s port %s' % server_address) sock.connect(server_address) try: # Send data message = 'This is the message. It will be repeated.' print(sys.stderr, 'sending "%s"' % message) sock.sendall(message) # Look for the response amount_received = 0 amount_expected = len(message) while amount_received < amount_expected: data = sock.recv(16) amount_received += len(data) print(sys.stderr, 'received "%s"' % data) finally: print(sys.stderr, 'closing socket') sock.close()

Пример с обработкой данных

В этом примере открывается сокет, который слушает входящие данные и обрабатывает их.

Подробности в комментариях к коду.

# Нужно принять сообщение типа # name=Sergey&last_name=Ivanov&birthday=1990-10-05 # и вытащить имя, фамилию и ДР # Используем модуль socket: import socket # Создаём сокет sock = socket.socket() # Выбираем хост и порт. # Хост сделаем пустым для большей доступности sock.bind(('', 9090)) # Запускаем режим прослушивания и определяем размер очереди sock.listen(1) # Принимаем подключение с помощью метода accept # accept возвращает кортеж (tuple) с двумя элементами # новый сокет и адрес клента # адрес клиент это тоже кортеж из двух элементов # IP это элемент с индексом 0 (class 'str') conn, addr = sock.accept() print('connected:', addr) client_ip = addr[0] # В my_list мы будем собирать символы по 4 чтобы понять # было два перевода строки или нет my_list = [] # my_decoded_list сделан для подстаховки, чтобы убедиться # что мы не приняли за перевод строки что-то другое # это ещё не реализовано my_decoded_list = [] # i просто считает символы i = 0 while True: symbol = conn.recv(1) # сюда нужно встроить проверку декодируется ли этот символ в принципе или нет # хотя бы try поставить decoded_symbol = symbol.decode('utf-8') my_list += symbol my_decoded_list += decoded_symbol # пока что мы не ожидаем сообщение # нужно дождаться двух переводов строки message_coming = False # поймали два перевода строки if i > 2 and my_list[i] == 10 and my_list[i - 1] == 13 and my_list[i - 2] == 10 and my_list[i - 3] == 13: # теперь мы ждём сообщение message_coming = not message_coming while message_coming == True: # о размере нужно договориться заранее # мы ждём до 2-х килобайт message = conn.recv(2048) # Декодируем из 'b' в 'str' decoded_message = message.decode('utf-8') # Проверяем что сообщение начинается с name, иначе нет смысла с ним # работать дальше if decoded_message[:5] == 'name=': # Разбиваем по разделительному символу & new_list = decoded_message.split('&') new_list_len = len(new_list) # Проверяем, что элемента три if new_list_len == 3: name = new_list[0][5:] last_name_check = new_list[1][:9] if last_name_check == 'last_name': last_name = new_list[1][10:] else: print("Error with last_name name") message_coming = False birthday = new_list[2][span class="lightblue">9:span class="lightblue">-2] print(name) print(last_name) print(birthday) if birthday: birthday_len = len(birthday) if birthday_len != 10: print(f"Error in birthday format. Expected len = 10." f"Actual len = {birthday_len}") # Здесь я шлю данные обратно, # но вообще можно вызывать какую-то функцию и передавать аргументы conn.send(bytes(name, 'utf-8')) conn.send(bytes(last_name, 'utf-8')) conn.send(bytes(birthday, 'utf-8')) conn.send(bytes(client_ip, 'utf-8')) print("OK") message_coming = False else: print(f"message is not full. Expected len = 3." f"Actual len = {new_list_len}") message_coming = False else: print("message is not of correct format") message_coming = False i += 1 if not symbol: break # Закрываем подключение # Как именно закрывется подключение я ещё не разобрался conn.close()

gethostbyname()

import socket def main(): print(resolve) ip = resolve("www.eth1.ru") print(ip) def resolve(host): return socket.gethostbyname(host) if __name__ == "__main__": main()

Пример с кэшированием gethostbyname() вы можете изучить здесь

Похожие статьи
Python
Интерактивный режим
dict, list, str
\: перенос строки
if, elif, else
Циклы
Функции
try except
Пакеты
ООП
Опеределить тип переменной Python
Работа с REST API на Python
Файлы: записать, прочитать…
Работа с базами данных
datetime: Дата и время в Python
json.dumps
Сложности при работе с Python
Фреймворки: Django, Flask
Виртуальное окружение
subprocess: bash команды из Python
multiprocessing: несколько процессов одновременно
psutil: cистемные ресурсы
sys.argv: аргументы командной строки
PyCharm: IDE
pydantic: валидация данных
paramiko: SSH из Python
logging: запись в лог
Обучение Python
Сокеты в Си

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: