Сетевое программирование на Python.
TCP клиент
Сначала мы создаем объект сокета при помощи параметров AF_INET и SOCK_STREAM ➊. Параметр AF_INET указывает, что мы будем использовать стандартный IPv4 адрес или имя хоста, а SOCK_STREAM указывает, что это будет TCP клиент. Затем мы соединяем клиент с сервером ➋ и посылаем некоторые данные ➌. Последний шаг — получение данных обратно и распечатка ответа ➍. Это простейшая форма TCP клиента, но именно ее вы будете писать чаще всего.
В сниппете кода выше мы делаем серьезные предположения о сокетах, о которых вам совершенно определенно нужно знать. Первое предположение заключается в том, что наше соединение всегда будет удачным, а второе — сервер всегда ожидает, что мы первые будет посылать данные (в отличие от серверов, которые первыми посылают данные и ждут вашего ответа). Наше третье предположение заключается в том, что сервер всегда всегда будет отсылать данные обратно своевременно. Мы сделали эти предположения для упрощения задачи.
UDP клиент
UDP клиент в Python не сильно отличается от TCP клиента, и нам нужно внести всего два небольших изменения, чтобы отправить пакеты в форме UDP.
Как видите, мы изменили тип сокета на SOCK_DGRAM ➊, создавая объект сокета. Следующий шаг — вызвать sendto() ➋, передать данные и отправить на нужный вам сервер. Так как UDP — это протокол без установления соединения, то мы не можем заранее вызвать connect(). Последний шаг - recvfrom() ➌. Он нужен, чтобы вернуть обратно данные UDP. Вы также заметите, что он возвращает как данные, так и детали удаленного хоста и порта.
TCP сервер
Создание TCP сервера на языке Python — так же просто, как и создание клиента. Возможно, вы захотите использовать свой собственный TCP сервер для написания командных оболочек или создания прокси (и тем, и другим мы займемся позже). Давайте начнем с создания стандартного многопоточного сервера.
Для начала мы передаем IP-адрес и порт, который сервер будет прослушивать ➊. Затем мы даем серверу задание начать прослушивание ➋ с максимальной очередью (backlog) соединений, заданной на 5. Затем мы запускаем главный цикл, где сервер будет ждать входящие соединения. Когда происходит соединение клиента ➍, мы получаем сокет клиента в переменной client и детали удаленного соединения в переменной addr. Затем мы создаем новый объект потока, который указывает на нашу функцию handle_client и передаем объект сокета как аргумент. Далее мы запускаем поток, чтобы установить соединение клиента ➎, и наш главный цикл готов к обработке другого входящего соединения. Функция handle_client ➌ выполняет recv() и затем отправляет простое сообщение обратно клиенту.
Если вы используете TCP клиент, который мы создали ранее, то вы можете передать тестовые пакеты на сервер и сможете увидеть следующее:
TCP клиент
Код:
import socket
target_host = "www.google.com"
target_port = 80
# create a socket object
➊ client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect the client
➋ client.connect((target_host,target_port))
# send some data
➌ client.send("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
# receive some data
➍ response = client.recv(4096)
print response
В сниппете кода выше мы делаем серьезные предположения о сокетах, о которых вам совершенно определенно нужно знать. Первое предположение заключается в том, что наше соединение всегда будет удачным, а второе — сервер всегда ожидает, что мы первые будет посылать данные (в отличие от серверов, которые первыми посылают данные и ждут вашего ответа). Наше третье предположение заключается в том, что сервер всегда всегда будет отсылать данные обратно своевременно. Мы сделали эти предположения для упрощения задачи.
UDP клиент
UDP клиент в Python не сильно отличается от TCP клиента, и нам нужно внести всего два небольших изменения, чтобы отправить пакеты в форме UDP.
Код:
import socket
target_host = "127.0.0.1"
target_port = 80
# create a socket object
➊ client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# send some data
➋ client.sendto("AAABBBCCC",(target_host,target_port))
# receive some data
➌ data, addr = client.recvfrom(4096)
print data
TCP сервер
Создание TCP сервера на языке Python — так же просто, как и создание клиента. Возможно, вы захотите использовать свой собственный TCP сервер для написания командных оболочек или создания прокси (и тем, и другим мы займемся позже). Давайте начнем с создания стандартного многопоточного сервера.
Код:
import socket
import threading
bind_ip = "0.0.0.0"
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
➊ server.bind((bind_ip,bind_port))
➋ server.listen(5)
print "[*] Listening on %s:%d" % (bind_ip,bind_port)
# this is our client-handling thread
➌ def handle_client(client_socket):
# print out what the client sends
request = client_socket.recv(1024)
print "[*] Received: %s" % request
# send back a packet
client_socket.send("ACK!")
client_socket.close()
while True:
➍ client,addr = server.accept()
print "[*] Accepted connection from: %s:%d" % (addr[0],addr[1])
# spin up our client thread to handle incoming data
➎ client_handler = threading.Thread(target=handle_client,args=(client,))
client_handler.start()
Если вы используете TCP клиент, который мы создали ранее, то вы можете передать тестовые пакеты на сервер и сможете увидеть следующее:
Код:
[*] Listening on 0.0.0.0:9999[*] Accepted connection from: 127.0.0.1:62512[*] Received: ABCDEF
Последнее редактирование: