Pull to refresh

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

Level of difficultyEasy

Всех приветствую, долго думал, написать статью или нет, но все же решился поделится такой забавной темой как сервер на 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)

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

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.