300 likes | 484 Views
Gniazda. Stworzenie gniazda: gniazdo.socket(rodzina,typ[,protokół]) Utworzy nowe gniazdo obsługujące daną rodzine adresów, o danym typie gniazda("SOCK_STREAM" dla gniazd TCP i SOCK_DGRAM dla UDP). Numer protokołu jest domyślnie 0 i można go swobodnie pominąć. Rodzina adresów.
E N D
Gniazda Stworzenie gniazda: gniazdo.socket(rodzina,typ[,protokół]) Utworzy nowe gniazdo obsługujące daną rodzine adresów, o danym typie gniazda("SOCK_STREAM" dla gniazd TCP i SOCK_DGRAM dla UDP). Numer protokołu jest domyślnie 0 i można go swobodnie pominąć
Rodzina adresów • AF_INET(domyślne) – Gniazdo IPv4 to gniazdo pomiędzy dwoma procesami, potencjalnie działającymi na dwóch maszynach używające obecnej wersji adresów IP. Ten typ jest obecnie najczęściej używany. W Pythonie gniazda IPv4 reprezentowane są w postaci tupli (host, port), gdzie host to łańcuch a port to liczba całkowita - numer portu. Jako host można podać IP lub adres www, np. www.google.pl
Rodzina adresów • AF_INET6 - Podobne do AF_INET, lecz używa IP w wersji 6, która to używa 128 bitowych adresów IP a nie 32 bitowych jak to robi obecnie stosowana wersja IPv4. W Pythonie gniazda tego typu reprezentowane są w postaci tupli (host, port, flowinfo, scopeid) gdzie "flowinfo" to identyfikator przepływu, a "scopeid" identyfikator zakresu. Obecnie IPv6 nie jest powszechnie stosowany.
Rodzina adresów • AF_UNIX - Gniazdo Unixowe umożliwia dwóm procesom działającym na tej samej maszynie do porozumiewania się. W Pythonie adresy gniazd Unixowych reprezentowane są w postaci łańcuchów.
Obsługa hostów i adresów • gethostname() – zwraca nazwe hosta komputera na którym polecenie zostało wywołane • gethostbyname(name) – zamienia danego hosta na adres IP lub zwraca wyjątek jeśli takiego hosta nie ma • gethostbyname_ex(name) – zwraca tuple zawierającą nazwe hosta, listę alternatywnych nazw hosta oraz liste adresów IP hosta
Obsługa hostów i adresów • gethostbyaddr(adres) – działa jak gethostbyname_ex, jedyną różnicą jest to że zamiast nazwy hosta funkcja dostaje string z adresem IP • getservbyname(usługa,protokół) – zwraca numer portu używany przez usługe(np. ‘telnet’ czy ‘http’) oraz port(np. ‘tcp’, ‘udp’)
Obsługa hostów i adresów • inet_aton(ip_adr) – otrzymany adres IP przekszatłca do 32-bitowej postaci • inet_ntoa(packed) – zwraca adres IP z otrzymanej 32-bitowej postaci • getfqdn(name) – zwraca nazwe domeny dla zadanego hosta, jeśli wstawimy pusty string zwraca pełną nazwe domeny dla localhosta
Obsługa hostów i adresów Moduł socket zawiera również zdefiniowane zmienne (32-bitowej postaci) reprezentujące zarezerwowane adresy IP, np.: INADDR_ANY INADDR_BROADCATS INADDR_LOOPBACK
Komunikacja • bind() – funkcja przywiązująca gniazdo do zadanego adresu, argumentem funkcji jest tupla zawierająca adres i numer portu • listen() – nasłuchuje połączeń do gniazda, parametrem jest maksymalna liczba połączeń dla gniazda ( SOMAXCONN – liczba max połączeń ) • accept() – akceptacja przychodzącego połaczenia do gniazda, zwraca nowe gniazdo i jego adres
Komunikacja • connect() – łączy gniazdo z gniazdem pod podanym adresem, podobnie jak w bind() adres musi być przekazany w tupli • connect_ex() – działa jak connect() lecz zamiast rzucać wyjątek zwraca error(liczbe różną od 0)
Wysyłanie danych • send(string[,flags]) – wysyła dane do połączonego gniazda • sendto(string[,flags],adres) – wysyła dane pod zadany adres Zarówno send() jak i sendto() zwracają liczbe wysłąnych bajtów
Odbieranie danych • recv(bufsize[,flags]) – odbiera dane od połączonego gniazda, parametrem jest rozmiar bufora • recvfrom(bufsize[,flags]) – działa dokładnie tak samo jak recv() ale zwraca dane w postaci (dane, (ipAdres,port) )
SERWER By stworzyć serwer musimy: • Stworzyć gniazdo • Przypisać gniazdo do adresu IP i portu • Nasłuchiwać nadchodzących połączeń • Oczekiwać klientów • Zaakceptować klienta • Wysyłać i odbierać dane
KLIENT By stworzyć klienta musimy: • Stworzyć gniazdo • Połączyć się z serwerem • Wysyłać i odbierać dane
Prosty serwer from socket import * import time s = socket(AF_INET, SOCK_STREAM) #utworzenie gniazda s.bind(('', 8888)) #dowiazanie do portu 8888 s.listen(5) while 1: client,addr = s.accept() # odebranie polaczenia print 'Polaczenie z ', addr client.send(str(time.ctime(time.time()))) # wyslanie danych do klienta client.close()
Prosty klient from socket import * s = socket(AF_INET, SOCK_STREAM) #utworzenie gniazda s.connect(('localhost', 8888)) # nawiązanie polaczenia tm = s.recv(1024) #odbior danych (max 1024 bajtów) s.close() print 'Czas serwera: ', tm
SocketServer Subklasy SocketServer: • TCPServer • UDPServer • UnixStreamServer • UnixDagramServer
Request Handlers • BaseRequestHandler – posiada wbudowane metody: setup(),handle,finish(), które można „nadpisać” swoimi własnymi metodami do obsługi naszego SocketServer. Przeważnie potrzeba nadpisać jedynie metodę handle(), która akceptuje połączenia i obsługuje serwer. setup inicjalizuje serwer, zaś finish do sprzątania wszelkiego powstałego bałaganu
Request Handlers • StreamRequestHandler • DatagramRequestHandler Zasadniczo działają jak BaseRequestHandler, nadpisują metody setup i finish zastępującje wfile i rfile, których używamy do wysłyłania i odczytu danych od klienta
HTTP • BaseHTTPRequestHandler – klasa dziedzicząca po StreamRequestHandler akceptująca połączenia HTTP. Odczytuje nagłówki i wywołuje odpowiednie metody obsługujące żądania. Klasy po niej dziedziczące nie powinny zmieniać __init__ ani handle lecz implementować tylko obsługe interesujących nas poleceń (GET, POST,PUT,etc) tworząc metodę klasy odpowiednio nazwaną: do_GET() do_POST() do_PUT()
Tworzenie metod klasy BaseHTTPRequestHandler • send_response(kod[,wiadomość]) – metoda która powinna być wywołana jako pierwsza w naszej własnej metodzie. Wysyła kod HTTP (np. 200) i opcjonalną wiadomość. • send_error(kod[,wiadomość]) – należy użyć jeśli żądanie jest nieprawidłowe • send_header(key,value) – wysyła nagłówek wiadomości • end_headers() – kończy część nagłówkową
Przykład def do_GET(self) self.send_response(200) self.send_header(‘Content-type’,’text/html) self.send_header(‘Content-lenght’,’len(data)’) self.end_headers() #wysłanie reszty danych
SimpleHTTPRequestHandler SimpleHTTPRequestHandler w przeciwieństwie do BaseHTTPRequestHandler dostarcza wbudowaną obsługę dla poleceń HEAD i GET. Dodatkowo SimpleHTTPRequestHandler posiada słownik extensions_map który przekształca pliki do typu MIME(Multipurpouse Internet Mail Extension) by przeglądarki mogły obsłużyć otrzymywany plik
CGIHTTPRequestHandler Rozszerza funkcjonalność SimpleHTTPRequest-Handler’a dodając obsługę skryptów CGI(Common Gateway Interface) będących standardowym sposobem tworzenia programów zezwalających na dodawanie przez użytkownika danych na serwer.Dla GET i POST sprawdza czy dany plik jest formatu CGI, jeśli tak uruchamia odpowiednie procesy, w przeciwnym wypadku odsyła go z powrotem do użytkownika
Otrzymywanie Zasobów Internetowych • urllib – biblioteka zawierająca narzędzia do pobierania danych z Internetu. Wspiera HTTP i FTP. • urllib2 – nowa i bardziej rozwinięta wersja biblioteki urllib
Funkcje biblioteki urllib • urlretrive(url[,filename[,callback]]) – pobiera dane z danego adresu url i zapisuje do pliku filename. callback jest funkcją uaktualniającą pasek postępu pobierania(otrzymuje 3 parametry: 1-liczba bloków już pobranych, 2-rozmiar poszczególnego bloku danych3-całowity rozmiar pliku • urlcleanup() – uwalnia zasoby wykożystywane w urlretrive
Manipulacja adresami URL • quote – koduje pewne znaki w adresie url na 16-stkowe wartosci • unquote – odkodowuje 16-stkowe wartosci z adresu url na normalną postać • quote_plus – działanie jak quote, dodatkowo spacje zamienia na ‘+’ • unquote_plus – odpowiednio
URL jako plik • urlopen(url[,data]) – tworzy i zwraca obiekt „plikowy” do kontaktu z zadanym urlem. Obiekt ten może być traktowany jak zwykły plik,np.:page-urllib.urlopen(‘http://www.wp.pl’) print len(page.read()) Parametr data jest używany do przekazania danych do żądania POST
Przygotował i przedstawił: Jan Figura