Сообщить об ошибке.

Функция create_server() модуля socket в Python

Создает TCP/IP сервер, который слушает Интернет адрес

Синтаксис:

import socket

sock = socket.create_server(address, *, family=AF_INET, 
                            backlog=None, reuse_port=False, 
                            dualstack_ipv6=False)

Параметры:

  • address - адресу сервера в виде (host, port),
  • family=AF_INET - семейства адресов,
  • backlog=None - размер очереди из клиентов,
  • reuse_port=False - следует ли устанавливать socket.SO_REUSEPORT,
  • dualstack_ipv6=False - поддержка IPv6.

Возвращаемое значение:

Описание:

Функция create_server() модуля socket создает сокет, слушающий TCP/IP подключения, привязанный к адресу address в виде 2-кортеж (host, port) и возвращает объект сокета.

Аргумент семейства адресов family должен быть socket.AF_INET или socket.AF_INET6.

Аргумент backlog - это размер очереди, переданной в метод объекта сокета Socket.listen(). Когда это значение равно 0, то выбирается разумное значение по умолчанию.

Аргумент reuse_port указывает, следует ли устанавливать параметр сокета socket.SO_REUSEPORT.

Если аргумент dualstack_ipv6=True и платформа его поддерживает, то сокет сможет принимать соединения как IPv4, так и IPv6, в противном случае возникнет ошибка ValueError.

Предполагается, что большинство платформ POSIX и Windows поддерживают эту функцию. Когда эта функция включена, то адрес, возвращаемый методом объекта сокета Socket.getpeername() при подключении IPv4, будет IPv6-адресом, представленным как IPv4-сопоставленный адрес.

Если для dualstack_ipv6=False, то метод объекта сокета Socket.getpeername() будет явно отключен на платформах, которые включают ее по умолчанию (например, Linux). Этот параметр можно использовать вместе с функцией socket.has_dualstack_ipv6():

import socket

# слушать все IP на порту 8080
addr = ('', 8080)
if socket.has_dualstack_ipv6():
    s = socket.create_server(addr, family=socket.AF_INET6, dualstack_ipv6=True)
else:
    s = socket.create_server(addr)

Примечание. На платформах POSIX параметр сокета socket.SO_REUSEADDR установлен для немедленного повторного использования предыдущих сокетов, которые были привязаны к тому же адресу и оставались в состоянии TIME_WAIT.

Новое в Python 3.8.

Пример создания простого TCP/IP сервера:

Так как мы имеем дело с сокетами, то для тестирования кода сервера, необходим клиент. Код клиента представлен ниже.

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

TCP/IP сервер.

# test-server.py
import socket

server_address = ('localhost', 8080)
with socket.create_server(server_address) as sock:
    while True:
        # ждем соединения
        print('Ожидание соединения...')
        connect, client_address = sock.accept()
        print('Подключено к:', client_address)
        # Принимаем данные порциями и ретранслируем их
        while True:
            data = connect.recv(16)
            print(f'Получено: {data.decode()}')
            if data:
                print('Обработка данных...')
                temp_data = data.decode('utf-8').upper()
                data = temp_data.encode('utf-8')
                print('Данные обработаны, отправка клиенту...')
                connect.sendall(data)
            else:
                print('Нет данных от:', client_address)
                break


# Ожидание соединения...
# Подключено к: ('127.0.0.1', 32800)
# Получено: Привет!
# Обработка данных...
# Данные обработаны, отправка клиенту...
# Получено: 
# Нет данных от: ('127.0.0.1', 32800)
# Ожидание соединения...

TCP/IP клиент.

# test-client.py
import socket

# Подключаем сокет к порту, через 
# который прослушивается сервер
server_address = ('localhost', 8080)
with socket.create_connection(server_address) as sock:
    print('Подключено к:', server_address)
    # Отправка данных
    mess = 'Привет!'
    print(f'Отправка: {mess}')
    message = mess.encode()
    sock.sendall(message)
    
    # Смотрим ответ
    amount_received = 0
    amount_expected = len(message)
    while amount_received < amount_expected:
        data = sock.recv(16)
        amount_received += len(data)
        mess = data.decode()
        print(f'Получено: {data.decode()}')

print('Отключено от:', server_address)

# Подключено к: ('localhost', 8080)
# Отправка: Привет!
# Получено: ПРИВЕТ!
# Отключено от: ('localhost', 8080)