Главная » Статьи » веб программирование |
Клиент-сервер (сетевое программирование)материал взят с сайта http://alex-ln.wix.com Попробуем разобраться с сетевым программированием в Python. Итак, прежде чем установить связь, сетевые приложения (клиент, сервер) сначала должны создать сокеты ("конечные точки связи"). Сокеты можно представить как сетевые розетки, с помощью которых (сейчас о сокетах, а не о розетках) приложения получают доступ к сети. По видам соединений сокеты разделяются на: сокеты с установлением соединения (TCP протокол, тип сокета = SOCK_STREAM) и без установления (UDP протокол, тип сокета = SOCK_DGRAM). Для создания объектов сокетов в python используется модуль socket и его функция socket().
Пример:
import socket
tcpS = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # создает TCP/IP сокет (объект), AF_INET (семейство адресов Интернета) говорит, что сокет будет сетевым (бывают еще файловые для взаимодействия процессов на одном ПК, кстати для работы в IPv6 семейство адресов будет AF_INET6), SOCK_STREAM - сокет будет работать через TCP.
udpS = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # создает UDP/IP сокет
Разобравшись с сокетами давайте создадим клиент-серверное приложение:
Серверная часть:
Схема сервера:
ss = socket() # создание сокета сервера ss.bind() # привязка сокета к адресу ss.listen() # прослушивание запросов на соединение inf_loop: # бесконечный цикл сервера cs = ss.accept() # прием клиентского запроса на установление соединения comm_loop: # цикл связи cs.recv() / cs.send() # обмен данными cs.close() # закрытие сокета клиента ss.close() # закрытие сокета сервера (необязательно)
Код:
from socket import *
HOST = '' # адрес хоста (сервера) пустой означает использование любого доступного адреса PORT = 21111 # номер порта на котором работает сервер (от 0 до 65525, порты до 1024 зарезервированы для системы, порты TCP и UDP не пересекаются) BUFSIZ = 1024 # размер буфера 1Кбайт ADDR = (HOST, PORT) # адрес сервера
tcpSerSock = socket(AF_INET, SOCK_STREAM) #создаем сокет сервера tcpSerSock.bind(ADDR) # связываем сокет с адресом tcpSerSock.listen(5) # устанавливаем максимальное число клиентов одновременно обслуживаемых
while True: # бесконечный цикл сервера print('Waiting for client...') tcpCliSock, addr = tcpSerSock.accept() # ждем клиента, при соединении .accept() вернет имя сокета клиента и его адрес (создаст временный сокет tcpCliSock) print('Connected from: {}'.format(addr)) while True: # цикл связи data = tcpCliSock.recv(BUFSIZ) # принимает данные от клиента if not data: break # разрываем связь если данных нет tcpCliSock.send(bytes('You sent me "{}"'.format(data.decode('utf8')), 'utf8')) # отвечаем клиенту его же данными tcpCliSock.close() # закрываем сеанс (сокет) с клиентом tcpSerSock.close() # закрытие сокета сервера
Клиентская часть:
Схема клиента:
cs = socket() # создание сокета клиента cs.connect() # попытка установить соединение с сервером comm_loop: # цикл связи cs.send()/cs.recv # прием передача данных cs.close()
Код:
from socket import *
HOST = 'адрес сервера' # локальный адрес localhost или 127.0.0.1 PORT = 21111 # порт на котором работает сервер BUFSIZ = 1024 ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) # установка связи с сервером
while True: data = input('>') # ввод данных для отправки if not data: break tcpCliScok.send(data.encode()) # отправка данных в bytes data = tcpCliSock.recv(BUFSIZ) # ожидание (получение) ответа if not data: break print(data.decode('utf8'))
tcpCliSock.close()
Теперь запускаем сначало сервер, потом клиент и обмениваемся сообщениями.
В отличие от TCP сервера UDP серверу не нужно устанавливать логическое соединение (избавляет от .listen()), а это значит, что нет необходимости "передавать" клиентский запрос на установление соединения в отдельный (временный) сокет.
Пример UDP сервера:
from socket import *
HOST = '' PORT = 21111 BUFSIZ = 1024 ADDR = (HOST, PORT)
udpSerSock = socket(AF_INET, SOCK_DGRAM) udpSerSock.bind(ADDR)
while True: print('Waiting...') data, addr = udpSerSock.recvfrom(BUFSIZ) # получает данные и адрес отправителя udpSerSock.sendto(bytes('You sent me "{}"'.format(data.decode('utf8')), 'utf8'), addr) # отвечает отправителю
udpSerSock.close()
С клиентом UDP думаю все понятно: отправка udpCliSock.sendto(data, ADDR) ; примем udpCliSock.recvfrom(BUFSIZ) Источник: http://alex-ln.wix.com/python#!%D0%9A%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80-%D1%81%D0%B5%D1% | |
Просмотров: 500 | |
Всего комментариев: 0 | |