UDP w Pythonie ============== Unicast ####### Klient ------ .. code-block:: python # -*- coding: utf-8 -*- import socket UDP_IP = "192.168.1.70" #Oczywiście wybierzcie inny adres IP UDP_PORT = 5005 MESSAGE = "Hello, World!" print("UDP target IP:", UDP_IP) print("UDP target port:", UDP_PORT) print("message:", MESSAGE) sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) sock.settimeout(1) try: response = sock.recv(1024) print(response) except socket.timeout: print("No response") Ważniejsze miejsca programu *************************** Stworzenie gniazda. Wybieramy rodzinę ``AF_INET``, oraz protokół ``SOCK_DATAGRAM``, czylu UDP. .. code-block:: python sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP Ustawienie czasu oczekiwania na odpowiedź, tutaj uwaga: w pytnonie tego typu interwały określa się jako zmienne float w sekundach --- zatem ``1`` oznacza 1 sekundę a ``1.5`` półtorej. .. code-block:: python sock.settimeout(1) Serwer ------ .. code-block:: python # -*- coding: utf-8 -*- import socket UDP_IP = "" UDP_PORT = 5005 sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP sock.bind((UDP_IP, UDP_PORT)) while True: data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes print("Otrzymalem:", data) sock.sendto("OK", addr) Ważniejsze miejsca programu *************************** Rozpoczęcie otrzymywania wiadomości z portu: .. code-block:: python sock.bind((UDP_IP, UDP_PORT)) Odczytanie pakietu. .. note:: By odpowiedzieć na pakiet UDP musimy znać adres z którego ów pakiet przyszedł, funkcja ``recvfrom`` zwraca dwie wartości --- otrzymane dane oraz adres z których je otrzymano. Składnia: .. code-block:: python data, addr = sock.recvfrom(1024) powoduje że pierwsza zwracana wartość trafia do zmiennej ``data`` a druga do ``addr``. .. code-block:: data, addr = sock.recvfrom(1024) sock.sendto("OK", addr) Broadcast ######### Serwer ------ Serwer jest bez zmian. Klient ------ Zmianie uległa jedna linijka kodu. .. code-block:: python # -*- coding: utf-8 -*- import socket UDP_IP = "192.168.1.255" UDP_PORT = 5005 MESSAGE = "Hello, World!" print("UDP target IP:", UDP_IP) print("UDP target port:", UDP_PORT) print("message:", MESSAGE) sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) sock.settimeout(1) try: response = sock.recv(1024) print(response) except socket.timeout: print("No response") Ważniejsze miejsca programu *************************** Ustawienie że gniazdo służy do broadcastów: .. code-block:: python sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) Multicast ######### Server ------ .. code-block:: python # -*- coding: utf-8 -*- import socket import struct import sys multicast_group = '224.3.29.71' server_address = ('', 10000) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(server_address) group = socket.inet_aton(multicast_group) mreq = struct.pack('4sL', group, socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) while True: print('\nwaiting to receive message') data, address = sock.recvfrom(1024) print('received %s bytes from %s' % (len(data), address)) print(data) print('sending acknowledgement to', address) sock.sendto('ack', address) Ważniejsze miejsca w programie: ******************************* Konwersja ciągu znaków na adres IP .. code-block:: python group = socket.inet_aton(multicast_group) Stworzenie struktury danych odpowiedzialnych za ustawienie adresu: .. code-block:: python mreq = struct.pack('4sL', group, socket.INADDR_ANY) Wartością opcji ``IP_ADD_MEMBERSHIP`` jest struktura ``ip_mreq``, tutaj pakujemy dwa obiekty pythona do takiego rozmiaru. Klient ------ Klient po prostu wysyła wiadomość na adres grupy.