Как стать автором
Обновить

Создание сервера на python 3 с использованием встроенной библиотеки socket

Уровень сложностиПростой

Всех приветствую, долго думал, написать статью или нет, но все же решился поделится такой забавной темой как сервер на python.

Начнем с создания двух файлов, назовем их: server.py и client.py.

Сторона сервера

Импортируем встроенные библиотеки - socket, time

Что это за библиотека?

Данная библиотека определяет низкоуровневый интерфейс для отправки запросов и их получения. Если проще, то данный модуль позволит нам создать сокет с определенным портом и определенным протоколов подключения (TCP, UDP).

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

Импортирование библиотеки и создание сокета:

import socket

main_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
main_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
main_socket.bind(("localhost", 5000))
main_socket.setblocking(0)
main_socket.listen(5)

clients_socket = []

Разберем каждую строку отдельно:

main_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - здесь мы создаем сам сокет с такими параметрами: socket.AF_INET - данная строчка говорит сокету, о том, какого формата адреса будут подключаться: в данном примере 4 - трех значных числа (127.0.0.1). socket.SOCK_STREAM - проток подключения (TCP), для UDP - SOCK_DGRAM.

main_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - данная строчка позволяет отключить Алгоритм Нейгла и позволить отправлять пакеты так же быстро, как мы их и получаем. Алгоритм Нейгла, уменьшает количество получаемых пакетов, за счет создания одно большого, в котором содержаться все остальные.

main_socket.bind(("localhost", 5000)) - здесь мы указываем на каком адресе будет сервер и по какому порту можно подключится. Порт можно выбрать любой, кроме диапазона от 0 до 1023, так как эти порты зарезервированы системой. Localhost означает, что данный сервер будет на одном ПК и подключится к нему с других ПК будет невозможно.

main_socket.setblocking(0) - данная строчка, позволяет нам не блокировать сервер, в ожидании пакетов от всех пользователей, а работать дальше.

main_socket.listen(5) - эта строчка позволяет прослушивать входящие сообщения от клиентов, ну а цифра 5, означает что максимальное число прослушивания 5.

Список clients_socket, будет хранить в себе сокеты всех подключенных клиентов.

Перейдем к циклу:

while True:

    #connect users
    try:
        new_socket, addres = main_socket.accept()
        new_socket.setblocking(0)
        print("Connect - ", addres)
        clients_socket.append(new_socket)

    except:
        pass

  time.sleep(0.01)

В данном цикле мы просматриваем не подключился ли кто то, без конструкции try, скрипт сразу выдаст ошибку, далее, если есть подключение, создается отдельный сокет с данными от клиента и отдельно берется его ip adress, ну и просто выводим в консоль клиент который подключился. Функция sleep в конце цикла, позволяет серверу работать, без данной функции, скрипт так же, выдаст ошибку из-за большой скорости.

Дополним цикл:

try:
        for sock in clients_socket:
            data = sock.recv(1024)
            data = data.decode()
            print(data)
    
    except:
        pass

    for sock in clients_socket:
        try:
            sock.send('Проверка связи'.encode())
            
        except:
            clients_socket.remove(sock)
            sock.close()

Пробегусь по основным методам:

recv(1024) - это обращение к сокету клиента, для чтения пакетов, которые он отправил, 1024 - это количество байт, которые хочет получить сервер от пользователя.

decode() - декодирование байтовой последовательности в привычный нами вид информации.

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

Сторона клиента:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
sock.connect(("localhost", 5000))

while True:

    data = sock.recv(1024)
    data = data.decode()
    print(data)

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

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.