Listen: примеры (PYTHON)

Метод listen в Python для прослушивания сетевых подключений
Раздел: Сокеты, Сетевые операции
listen(backlog): None

Основы функции listen

Метод listen() в Python применяется для объектов сокетов и переводит их в состояние прослушивания входящих подключений. Он используется при создании сетевых серверов, принимающих TCP-соединения.

Аргументы:

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

Метод не возвращает значений. Вызов listen() без предварительного связывания с адресом через bind() приводит к ошибке.

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

Простейший сервер с использованием listen:

import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8888))
server_socket.listen(1)
print("Сервер слушает порт 8888")
client_socket, addr = server_socket.accept()
print(f"Подключение от {addr}")
client_socket.close()
server_socket.close()
Сервер слушает порт 8888
Подключение от ('127.0.0.1', 54321)

Использование другого значения backlog:

server_socket.listen(10)
print(f"Сервер настроен на очередь из 10 подключений")
Сервер настроен на очередь из 10 подключений

Похожие функции в Python

Для создания сетевых серверов в Python существуют альтернативные инструменты.

  • socketserver - высокоуровневый модуль, упрощающий создание серверов. Подходит для быстрого прототипирования, скрывает детали обработки подключений.
  • asyncio.start_server() - асинхронная функция для создания серверов. Используется в асинхронном коде, эффективно обрабатывает множество одновременных подключений.
  • multiprocessing.Listener - объект для межпроцессного взаимодействия. Создает сервер для обмена данными между процессами, не использует сетевые порты.

Выбор зависит от задач: для простых TCP-серверов подходит socket.listen(), для асинхронных приложений - asyncio, для высокоуровневых решений - socketserver.

Аналоги в других языках

PHP: Функция socket_listen() выполняет ту же роль.

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '127.0.0.1', 8888);
socket_listen($socket, 5);
echo "Сервер слушает";
Сервер слушает

JavaScript (Node.js): Метод server.listen() у объекта net.Server.

const net = require('net');
const server = net.createServer();
server.listen(8888, 'localhost');
console.log("Сервер запущен");
Сервер запущен

Java: Метод ServerSocket.listen() отсутствует, прослушивание начинается после создания объекта с указанием порта.

ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("Сервер запущен");
Сервер запущен

C#: Метод TcpListener.Start() начинает прослушивание.

TcpListener listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();
Console.WriteLine("Сервер запущен");
Сервер запущен

Типичные ошибки

Вызов listen() до метода bind() вызывает ошибку.

import socket

sock = socket.socket()
try:
    sock.listen()
except OSError as e:
    print(f"Ошибка: {e}")
Ошибка: [Errno 22] Invalid argument

Указание отрицательного значения backlog приводит к ошибке в некоторых системах.

server_socket.bind(('localhost', 8888))
try:
    server_socket.listen(-1)
except OverflowError as e:
    print(f"Ошибка: {e}")
Ошибка: can't convert negative int to unsigned

Попытка использования на сокете, уже переведенном в состояние прослушивания.

server_socket.listen()
server_socket.listen()  # Повторный вызов
# Ошибки не возникает, но это избыточная операция

Изменения в последних версиях

В Python 3.5 появилась поддержка контекстного менеджера для объектов сокетов, что упрощает их закрытие, но не затрагивает непосредственно метод listen().

В Python 3.8 оптимизирована внутренняя реализация сетевого стека, что может влиять на производительность listen() при больших значениях backlog, но синтаксис и поведение остались прежними.

Начиная с Python 3.10, в документации явно указано, что значение backlog может быть установлено в 0 для отключения очереди подключений, хотя такая возможность существовала и ранее.

Расширенные примеры

Сервер с обработкой нескольких клиентов в цикле:

Пример python
import socket

server = socket.socket()
server.bind(('', 9090))
server.listen(3)
print("Сервер запущен")

while True:
    client, addr = server.accept()
    data = client.recv(1024)
    print(f"От {addr}: {data.decode()}")
    client.send(b"Hello from server")
    client.close()
Сервер запущен
От ('127.0.0.1', 54321): Привет
От ('127.0.0.1', 54322): Тест

Использование backlog равным 0, что отключает очередь подключений:

Пример python
server_socket.listen(0)
print("Очередь подключений отключена, новые соединения будут немедленно отклоняться, если сервер занят")
Очередь подключений отключена, новые соединения будут немедленно отклоняться, если сервер занят

Создание сервера с возможностью повторного использования адреса:

Пример python
server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('localhost', 8888))
server.listen()
print("Сервер с возможностью повторного использования адреса")
Сервер с возможностью повторного использования адреса

Измерение времени между вызовом listen и первым accept:

Пример python
import time

server.listen(5)
start = time.time()
client, addr = server.accept()
elapsed = time.time() - start
print(f"Первый клиент подключился через {elapsed:.2f} секунд")
Первый клиент подключился через 1.53 секунд

питон listen function comments

En
Listen Enable server to accept connections