Internet niezaprzeczalnie stał się „duszą istnienia”, a jego aktywność charakteryzuje się „połączeniami” lub „sieciami”. Te sieci są możliwe dzięki jednej z najważniejszych podstaw platformy Gniazda. W tym artykule omówiono wszystkie obszary dotyczące programowania w gniazdach w języku Python. Gniazda pomagają w tworzeniu tych połączeń, podczas gdy niewątpliwie ułatwia to.
Rzućmy okiem na wszystkie tematy omówione w tym artykule:
Dlaczego warto korzystać z gniazd?
Co to są gniazda w Pythonie?
Jak osiągnąć programowanie w gniazdach w Pythonie
Co to jest serwer?
Kim jest klient?
Echo Client-Server
Wiele komunikacji
Przesyłanie obiektów Pythona
Dlaczego warto korzystać z gniazd?
Gniazda są kręgosłupem sieci. Umożliwiają przesyłanie informacji między dwoma różnymi programami lub urządzeniami. Na przykład, gdy otwierasz przeglądarkę, jako klient tworzysz połączenie z serwerem w celu przesyłania informacji.
Zanim zagłębimy się w tę komunikację, najpierw dowiedzmy się, czym dokładnie są te gniazda.
Co to są gniazda?
Ogólnie rzecz biorąc, gniazda to wewnętrzne punkty końcowe zbudowane do wysyłania i odbierania danych. Pojedyncza sieć będzie miała dwa gniazda, po jednym dla każdego komunikującego się urządzenia lub programu. Te gniazda są połączeniem adresu IP i portu. Pojedyncze urządzenie może mieć liczbę „n” gniazd zależną od numeru używanego portu. Dostępne są różne porty dla różnych typów protokołów. Spójrz na poniższy obraz, aby uzyskać więcej informacji o niektórych typowych numerach portów i powiązanych protokołach:
Teraz, gdy już wiesz, czym są gniazda, przyjrzyjmy się teraz modułowi Socket w Pythonie:
Jak osiągnąć programowanie w gniazdach w Pythonie:
Aby osiągnąć programowanie w gniazdach w Pythonie, musisz zaimportować plik gniazdo elektryczne moduł lub . Ten moduł składa się z wbudowanych metod, które są wymagane do tworzenia gniazd i pomagają im się kojarzyć.
Niektóre z ważnych metod są następujące:
Metody | Opis |
gniazdo.socket () | używane do tworzenia gniazd (wymagane na obu końcach serwera i klienta do tworzenia gniazd) |
socket.accept () | używany do akceptowania połączenia. Zwraca parę wartości (conn, adres), gdzie conn to nowy obiekt gniazda do wysyłania lub odbierania danych, a adres to adres gniazda znajdującego się na drugim końcu połączenia |
socket.bind () | używany do tworzenia powiązania z adresem podanym jako parametr |
socket.close () | służy do oznaczenia gniazda jako zamkniętego |
socket.connect () | używany do łączenia się ze zdalnym adresem podanym w parametrze |
socket.listen () | umożliwia serwerowi akceptowanie połączeń |
Teraz, gdy zrozumiałeś znaczenie modułu gniazda, przejdźmy do tego, jak może on służyć do tworzenia serwerów i klientów do programowania w gniazdach w .
Co to jest serwer?
Serwer to program, komputer lub urządzenie służące do zarządzania zasobami sieciowymi. Serwery mogą znajdować się na tym samym urządzeniu lub komputerze, mogą być lokalnie połączone z innymi urządzeniami i komputerami, a nawet zdalnie. Istnieją różne typy serwerów, takie jak serwery baz danych, serwery sieciowe, serwery druku itp.
Serwery często używają metod, takich jak socket.socket (), socket.bind (), socket.listen () itp. Do nawiązywania połączenia i tworzenia powiązań z klientami. Teraz napiszmy program do stworzenia serwera. Rozważmy następujący przykład:
PRZYKŁAD:
import socket s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.bind ((socket.gethostname (), 1234)) # numer portu może być dowolną wartością z zakresu od 0 do 65535 (zazwyczaj podajemy nieobsługiwane porty, które są > 1023) s.listen (5) while True: clt, adr = s.accept () print (f'Connection to {adr} added ') #f string to dosłowny ciąg znaków z prefiksem f, który # zawiera wyrażenia Pythona w nawiasach klamrowych clt .send (bytes ('Socket Programming in Python', 'utf-8')) # do wysyłania informacji do clientocket
Jak widać, pierwszą koniecznością utworzenia gniazda jest zaimportowanie modułu gniazda. Następnie metoda socket.socket () jest używana do tworzenia gniazda po stronie serwera.
UWAGA:
AF_INET odnosi się do adresu z Internetu i wymaga pary (host, port), gdzie hostem może być URL określonej witryny internetowej lub jej adres, a numer portu jest liczbą całkowitą. SOCK_STREAM służy do tworzenia protokołów TCP.
Metoda bind () przyjmuje dwa parametry jako krotkę (host, port). Jednak lepiej jest używać 4-cyfrowych numerów portów, ponieważ niższe numery są zwykle zajęte. Metoda Listen () umożliwia serwerowi akceptowanie połączeń. Tutaj 5 to kolejka dla wielu połączeń, które pojawiają się jednocześnie. Minimalna wartość, jaką można tutaj określić, to 0 (jeśli podasz mniejszą wartość, zostanie zmieniona na 0). W przypadku, gdy żaden parametr nie jest określony, przyjmuje domyślny odpowiedni.
Plik umożliwia wieczne przyjmowanie połączeń. „Clt” i „adr” to obiekt i adres klienta. Instrukcja print po prostu wypisuje adres i numer portu gniazda klienta. Wreszcie clt.send jest używany do wysyłania danych w bajtach.
Teraz, gdy nasz serwer jest gotowy, przejdźmy do klienta.
Co to jest klient?
Klient to komputer lub oprogramowanie, które otrzymuje informacje lub usługi z serwera. W module klient-serwer klienci żądają usług z serwerów. Najlepszym przykładem jest przeglądarka internetowa, taka jak Google Chrome, Firefox itp. Te przeglądarki internetowe żądają od serwerów WWW wymaganych stron internetowych i usług zgodnie z instrukcjami użytkownika. Inne przykłady obejmują gry online, czaty online itp.
Przyjrzyjmy się teraz, jak zakodować program po stronie klienta :
PRZYKŁAD:
jaka jest różnica między xml a html
import socket s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect ((socket.gethostname (), 2346)) msg = s.recv (1024) print (msg.decode ('utf-8') )
Pierwszym krokiem jest zaimportowanie modułu gniazda, a następnie utworzenie gniazda, tak jak podczas tworzenia serwera. Następnie, aby utworzyć połączenie między klientem a serwerem, należy użyć metody connect (), podając (host, port).
UWAGA: gethostname jest używane, gdy klient i serwer znajdują się na tym samym komputerze. (LAN - localip / WAN - publicip)
Tutaj klient chce otrzymać pewne informacje z serwera iw tym celu należy użyć metody recv (), a informacje są przechowywane w innej zmiennej msg. Należy tylko pamiętać, że przekazywane informacje będą w bajtach, a klient w powyższym programie może otrzymać do 1024 bajtów (rozmiar bufora) w jednym transferze. Można określić dowolną kwotę w zależności od ilości przesyłanych informacji.
Na koniec przesyłana wiadomość powinna zostać zdekodowana i wydrukowana.
Teraz, gdy wiesz już, jak tworzyć programy typu klient-serwer, przejdźmy dalej, aby zobaczyć, jak należy je wykonywać.
Klient-serwer Echo:
Aby uruchomić te programy, otwórz wiersz poleceń, przejdź do folderu, w którym utworzyłeś program klienta i serwera, a następnie wpisz:
py server.py (tutaj server.py to nazwa pliku serwera, możesz też użyć py -3.7 server.py)
Po wykonaniu tej czynności serwer zacznie działać. Aby uruchomić klienta, otwórz kolejne okno cmd i wpisz:
py client.py (tutaj client.py jest nazwą pliku klienta)
WYJŚCIE (SERWER):
(KLIENT)
Wypróbujmy ten sam program, zmniejszając rozmiar bufora do 7 i zobaczmy, jakie dane wyjściowe otrzymamy:
WYNIK:
Jak widać, połączenie jest przerywane po przesłaniu 7 bajtów. Jest to jednak problem, ponieważ nie otrzymałeś pełnych informacji i połączenie jest zamknięte. Przejdźmy do rozwiązania tego problemu.
Wiele komunikacji:
Aby połączenie mogło trwać, dopóki klient nie otrzyma kompletnych informacji, możesz skorzystać z pętli while:
PRZYKŁAD:
import socket s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect ((socket.gethostname (), 2346)) while True: msg = s.recv (7) print (msg.decode ('utf- 8 '))
Gdy to zrobisz, cała wiadomość zostanie odebrana w 7 bajtach na transfer.
Ale tym razem, jak widać, połączenie nie jest przerywane i nigdy nie wiadomo, kiedy to się stanie. A do tego, co się stanie, jeśli tak naprawdę nie wiesz, jak duża jest wiadomość lub informacja, którą klient otrzyma z serwera. W takich przypadkach możesz faktycznie użyć następującego fragmentu kodu po stronie klienta:
PRZYKŁAD:
complete_info = '' while True: msg = s.recv (7) if len (msg)<=0: break complete_info += msg.decode('utf-8') print(complete_info)
Po stronie serwera użyj metody close () w następujący sposób:
clt.close ()
Wynik tego będzie taki, jak pokazano na poniższym obrazku:
java, aby zakończyć program
WYNIK:
Wszystko, co robi powyższy blok kodu, polega na sprawdzaniu rozmiaru informacji i drukowaniu ich w buforze po dwa bajty na raz oraz zamykaniu połączenia po jego zakończeniu.
Przesyłanie obiektów Pythona:
Do tej pory masz talent do przenoszenia strun. Ale programowanie gniazd w Pyton pozwala również na przesyłanie obiektów Pythona. Te obiekty mogą być dowolnymi obiektami, takimi jak zestawy, krotki, słowniki itp. Aby to osiągnąć, musisz zaimportować moduł pikle z Pythona.
Moduł Python pickle:
Moduł Python pickle pojawia się, gdy faktycznie serializujesz lub deserializujesz obiekty w Pythonie. Spójrzmy na mały przykład,
PRZYKŁAD:
import pickle mylist = [1,2, 'abc'] mymsg = pickle.dumps (mylist) print (mymsg)
WYNIK: b’x80x03] qx00 (Kx01Kx02Xx03x00x00x00abcqx01e. ”
Jak widać, w powyższym programie „mylist” jest serializowany przy użyciu funkcji dumps () modułu pickle. Zwróć też uwagę, że dane wyjściowe zaczynają się od „b”, co oznacza, że są konwertowane na bajty. W programowaniu gniazd można zaimplementować ten moduł do transferu obiekty Pythona między klientami a serwerami.
Jak używać modułu pickle do przenoszenia struktur obiektów Pythona?
Kiedy używasz pickle wraz z gniazdami, możesz absolutnie przesyłać wszystko przez sieć. Zapiszmy odpowiedniki po stronie serwera i klienta, aby przesłać listę z serwera do klienta:
Po stronie serwera:
import socket import pickle a = 10 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.bind ((socket.gethostname (), 2133)) #binding tuple s.listen (5) while True: clt, adr = s.accept () print (f'Połączenie z {adr} ustanowione ') m = {1:' Klient ', 2:' Serwer '} mymsg = pickle.dumps (m) # wiadomość, którą chcemy wydrukować później mymsg = {len (mymsg): {a}} 'utf-8') + mymsg clt.send (mymsg)
Tutaj m jest słownikiem, który jest w zasadzie a który musi zostać wysłany z serwera do klienta. Odbywa się to najpierw poprzez serializację obiektu za pomocą dumps (), a następnie konwertowanie go na bajty.
Zapiszmy teraz odpowiednik po stronie klienta:
Strona klienta:
import socket import pickle a = 10 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect ((socket.gethostname (), 2133)) while True: complete_info = b '' rec_msg = True while True: mymsg = s.recv (10) if rec_msg: print (f'The length of message = {mymsg [: a]} ') x = int (mymsg [: a]) rec_msg = False complete_info + = mymsg if len (complete_info) -a == x: print ('Otrzymano pełne informacje') print (complete_info [a:]) m = pickle.loads (complete_info [a:]) print (m) rec_msg = True complete_info = b '' print (complete_info )
Pierwsza pętla while pomoże nam śledzić całą wiadomość (complete_info), a także wiadomość, która jest odbierana (rec_msg) przy użyciu bufora. wiadomość przez ustawienie rec_
Następnie, gdy wiadomość jest odbierana, wszystko, co robię, to drukowanie każdego jej bitu i odbieranie go w buforze o rozmiarze 10. Ten rozmiar może być dowolny, w zależności od twojego osobistego wyboru.
Następnie, jeśli otrzymana wiadomość jest równa całej wiadomości, po prostu drukuję wiadomość jako otrzymaną pełne informacje, po czym zdeserializowałem wiadomość za pomocą load ().
Dane wyjściowe powyższego programu są następujące:
To prowadzi nas do końca tego artykułu o programowaniu za pomocą gniazd w Pythonie. Mam nadzieję, że dobrze zrozumiałeś wszystkie pojęcia.
Upewnij się, że ćwiczysz jak najwięcej i cofnij swoje doświadczenie.Masz do nas pytanie? Wspomnij o tym w sekcji komentarzy na blogu „Programowanie gniazd w Pythonie”, a my skontaktujemy się z Tobą tak szybko, jak to możliwe.
Aby uzyskać dogłębną wiedzę na temat języka Python i jego różnych aplikacji, możesz zarejestrować się na żywo z całodobowym wsparciem i dożywotnim dostępem.