Programowanie gniazd w Pythonie: Klient, serwer, biblioteki peer
Published: 2023-12-11 07:55:28

W tym samouczku dowiesz się, jak wymieniać dane między klientem a serwerem przy użyciu programowania gniazd Pythona i interfejsu API Socket. W dalszej części tego samouczka omówiona zostanie bezpośrednia wymiana danych między dwoma lub więcej klientami Pythona przy użyciu hostowanego dostawcy. Kod źródłowy użyty w tym samouczku można znaleźć w repozytorium [repozytorium GitHub](https://github.com/PubNubDevelopers/python-socket-demo).

Programowanie gniazd łączy dwa gniazda (gniazdo klienta i gniazdo serwera) i umożliwia im dwukierunkową komunikację w czasie rzeczywistym. Bezpośrednie połączenia gniazd mogą przynieść korzyści wszystkim aplikacjom działającym w czasie rzeczywistym, ponieważ dane mogą być wysyłane lub odbierane w dowolnym momencie.

Czy Python jest dobry do programowania gniazd?
----------------------------------------------

Tak! Python jest doskonałym wyborem do programowania gniazd, ponieważ ma wiele wbudowanych wymaganych modułów, takich jak gniazdo, wybierz i asyncio do tworzenia aplikacji klient-serwer.

### Do czego służą gniazda w Pythonie?

Gniazda Python są używane w aplikacjach, które muszą komunikować się przez sieć: takich jak serwery WWW, aplikacje do czatu lub klienci poczty e-mail. Program serwera nasłuchuje i obsługuje połączenia przychodzące, podczas gdy klient łączy się z serwerem w celu wysyłania i odbierania danych. Gniazda Pythona obsługują zarówno [TCP](https://www.pubnub.com/guides/tcp-ip/) [\-](https://www.pubnub.com/guides/udp/)niezawodny protokół, który zapewnia dostarczanie pakietów w kolejności, jak i [UDP -](https://www.pubnub.com/guides/udp/)bezpołączeniowy i lekki protokół dla aplikacji, w których utrata pakietów jest akceptowalna.

### Jak uruchomić program gniazda w Pythonie?

Poniższy przewodnik przeprowadzi Cię przez proces tworzenia klienta i serwera Pythona, które mogą się ze sobą komunikować. Oba programy należy uruchomić osobno, tj:

`python myServer.py`

`python myClient.py`

Konfiguracja środowiska**programistycznego Py** thon
----------------------------------------------------

Potrzebna będzie stabilna wersja [Python w wersji 3.x](https://www.python.org/downloads/) Jeśli jesteś użytkownikiem systemu Windows, masz możliwość dodania Pythona do swojej PATH.

Będziesz także potrzebował edytora kodu, aby postępować zgodnie z tym samouczkiem. [Visual Studio Code](https://code.visualstudio.com/) to popularny, darmowy edytor kodu typu open source, który obsługuje wiele języków i frameworków, w tym Python. VSCode obsługuje również rozszerzenia dla Pythona, aby pomóc w uzupełnianiu kodu i debugowaniu.

Tworzenie i uruchamianie aplikacji gniazda Python
-------------------------------------------------

Zbudujmy prostą aplikację gniazda przy użyciu Pythona. Python udostępnia natywną klasę [klasę gniazda](https://docs.python.org/3/library/socket.html) (moduł gniazda), więc programiści nie muszą polegać na zewnętrznych bibliotekach. Rozpocznij od skonfigurowania klienta i serwera programowania gniazd w Pythonie:

![](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jhj/bf547110b07a076c30bac70e1b5a7e9a/python-socket-connection-diagram.png)

### Zaimportuj bibliotekę gniazd Pythona

Utwórz plikclient.py w katalogu projektu. Aby korzystać z gniazd, zaimportuj bibliotekę gniazd Pythona i utwórz nowy obiekt gniazda, który łączy się z określonym adresem IP (w tym przypadku localhost na porcie numer 8080, ale możesz wybrać dowolny adres ipv4). Utwórz nowe połączenie z serwerem gniazd, wyślij dane do serwera TCP i zamknij połączenie gniazda.

Plik client.py powinien wyglądać następująco:

```js
import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('0.0.0.0', 8080)) client.send("I am CLIENT\n".encode()) from_server = client.recv(4096) client.close() print (from_server.decode())
```

Będziesz potrzebował serwera gniazd, aby nasłuchiwać połączeń przychodzących i wiadomości od klienta. Utwórz plik server.py i dodaj następującą zawartość:

```js
import socket serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serv.bind(('0.0.0.0', 8080)) serv.listen(5) while True: conn, addr = serv.accept() from_client = '' while True: data = conn.recv(4096) if not data: break from_client += data.decode('utf8') print (from_client) conn.send("I am SERVER\n".encode()) conn.close() print ('client disconnected and shutdown')
```

Server.py wiąże obiekt gniazda z nazwą hosta (localhost) na porcie 8080 i stale nasłuchuje nowych połączeń klienckich. Gdy klient łączy się z tym adresem, serwer akceptuje połączenie i odczytuje wszelkie dane. Po pomyślnym odczytaniu danych od klienta, serwer dostarcza odpowiedź z danymi, w którym to momencie klient kończy połączenie.

### Testowanie programowania gniazd w Pythonie

Aby przetestować to samodzielnie, otwórz jednocześnie dwa okna terminala. W jednym oknie uruchom:

```js
python3 server.py
```

W drugim oknie uruchom:

```js
python3 client.py
```

Zwróć uwagę, że serwer nadal działa i nawiąże nowe połączenie za każdym razem, gdy uruchomisz klienta i dołączysz nowe dane wyjściowe.

Klient wyśle ciąg "I am CLIENT" do serwera i będzie czekał na odpowiedź. Serwer odczyta wiadomość klienta, wyśle ją do terminala i odeśle odpowiedź do klienta.

![](https://images.ctfassets.net/3prze68gbwl1/6Y2HAKVJOGza5CUHcJyg8k/2480975a9fecd808b273cdf834ecb65b/python_sockets.png)

Programowanie gniazd w Pythonie przy użyciu PubNub
--------------------------------------------------

Do tej pory ten samouczek obejmował wymianę wiadomości między serwerem a klientem, ale co zrobić, jeśli trzeba komunikować się bezpośrednio między klientami Pythona?

Wysyłanie danych bezpośrednio między dwoma lub więcej urządzeniami klienckimi jest trudne, ponieważ wraz ze wzrostem liczby urządzeń pojawia się wiele kwestii związanych ze skalowaniem i bezpieczeństwem. Architektura klient-serwer jest używana do moderowania i zarządzania komunikacją między klientem a klientem. Jeśli nie masz serwera WWW lub martwisz się o skalowanie serwera, aby sprostać wymaganiom aplikacji, powinieneś zdecydować się na hostowane rozwiązanie do komunikacji w czasie rzeczywistym, takie jak [PubNub](https://www.pubnub.com/). PubNub to globalnie rozproszona i skalowalna platforma chmurowa, dzięki czemu nie musisz martwić się o wdrażanie i utrzymywanie serwerów. Wieloplatformowe zestawy SDK PubNub, w tym [Python](https://www.pubnub.com/docs/sdks/python)mogą identyfikować użytkowników i wysyłać wiadomości do określonych kanałów, które otrzymają tylko subskrybowani klienci.

### Programowanie gniazd Python klient-klient

W jaki sposób prosta aplikacja przedstawiona wcześniej mogłaby zostać napisana przy użyciu PubNub, aby wymieniać wiadomości bezpośrednio między dwoma klientami? Ważne jest, aby zrozumieć, że chociaż PubNub wykorzystuje architekturę "publikuj" i "subskrybuj" (pub/sub) do wysyłania i odbierania dwukierunkowych wiadomości między punktami końcowymi, to nadal używa gniazd za kulisami. PubNub zapewnia korzyści płynące z komunikacji gniazdowej bez martwienia się o szczegóły programowania sieciowego w Pythonie i utrzymywania zawsze włączonego połączenia między klientami niezależnie od systemu operacyjnego.

Aby zintegrować PubNub z projektem, zainstaluj pakiet PubNub za pomocą pip w terminalu; pozwoli ci to na korzystanie z [PubNub Python SDK](https://www.pubnub.com/docs/sdks/python) i komunikację z infrastrukturą PubNub.

```js
pip3 install 'pubnub>=7.1.0'
```

Będziesz musiał utworzyć dwóch klientów, aby połączyć się i komunikować za pośrednictwem sieci PubNub. Utwórz plik pn\_client\_1.py i dodaj następujący kod:

```js
from pubnub.callbacks import SubscribeCallback from pubnub.enums import PNStatusCategory from pubnub.pnconfiguration import PNConfiguration from pubnub.pubnub import PubNub import time import os pnconfig = PNConfiguration() userId = os.path.basame(__file__) pnconfig.publish_key = 'demo' pnconfig.subscribe_key = 'demo' pnconfig.user_id = userId pnconfig.ssl = True pubnub = PubNub(pnconfig) def my_publish_callback(envelope, status): # Check whether request successfully completed or not if not status.is_error(): pass class MySubscribeCallback(SubscribeCallback): def presence(self, pubnub, presence): pass def status(self, pubnub, status): pass def message(self, pubnub, message): if message.publisher == userId : return print ("z urządzenia " + message.publisher + ": " + message.message) pubnub.add_listener(MySubscribeCallback()) pubnub.subscribe().channels("chan-1").execute() ## publish a message while True: msg = input("") if msg == 'exit': os._exit(1) pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)
```

Utwórz plik pn\_client\_2.py i dodaj ten sam kod, którego użyłeś dla pn\_client\_1.py

Powyższy kod używa kluczy "demo", ale można uzyskać niestandardowe klucze [PubNub keys](https://admin.pubnub.com/#/register) za darmo.

Uruchom pn\_client\_1.py i pn\_client\_2.py jednocześnie w dwóch różnych oknach terminala

```js
python3 pn_client_1.py
```

```js
python3 pn_client_2.py
```

Każdy klient inicjuje swoje połączenie z siecią PubNub i subskrybuje otrzymywanie nowych wiadomości za każdym razem, gdy są one publikowane na kanale "chan-1". Można o tym myśleć jak o wysyłaniu danych przez gniazdo TCP w Pythonie; za kulisami PubNub tworzy i zarządza gniazdem dla ciebie i kieruje twoją wiadomość do wszystkich klientów, którzy jej nasłuchują. Gdy zdalny klient otrzyma wiadomość, jest ona wyświetlana w wierszu poleceń.

![](https://images.ctfassets.net/3prze68gbwl1/7BRsG0oVaACcE34x7eC0yC/475d6a894f0bc535bc70d213a9e8c189/python_pubnub.png)

I to już wszystko!

Jaka jest alternatywa dla gniazd w Pythonie?
--------------------------------------------

Aby uzyskać więcej informacji na temat rozwoju z PubNub, sprawdź ich zakres [samouczków](https://www.pubnub.com/tutorials/) i [dema](https://www.pubnub.com/demos/)Alternatywnie, sprawdź [Interaktywna wycieczka po PubNub](https://www.pubnub.com/tour/introduction/) aby zrozumieć, w jaki sposób platforma zapewnia interaktywność aplikacji w czasie rzeczywistym. PubNub obsługuje komunikację za pośrednictwem datagramów TCP i UDP, a także systemy Linux, Unix i Windows.

Dysponujemy obszerną kolekcją zasobów dotyczących przesyłania wiadomości w czasie rzeczywistym, w tym napisanymi przez ekspertów artykułami i przewodnikami na temat Websockets. Oto kilka cennych linków, z którymi warto się zapoznać.

-   [Czym są Websockets](https://www.pubnub.com/guides/what-are-websockets-and-when-should-you-use-them/)
    
-   [Zasoby PubNub](https://www.pubnub.com/resources)
    
-   [Blog PubNub](https://www.pubnub.com/blog/)
    

Jak PubNub może ci pomóc?
=========================

Ten artykuł został pierwotnie opublikowany na [PubNub.com](https://pubnub.com/blog/socket-programming-in-python-client-server-p2p/)

Nasza platforma pomaga programistom tworzyć, dostarczać i zarządzać interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych i urządzeń IoT.

Podstawą naszej platformy jest największa w branży i najbardziej skalowalna sieć komunikacyjna w czasie rzeczywistym. Dzięki ponad 15 punktom obecności na całym świecie obsługującym 800 milionów aktywnych użytkowników miesięcznie i niezawodności na poziomie 99,999%, nigdy nie będziesz musiał martwić się o przestoje, limity współbieżności lub jakiekolwiek opóźnienia spowodowane skokami ruchu.

Poznaj PubNub
-------------

Sprawdź [Live Tour](https://www.pubnub.com/tour/introduction/), aby zrozumieć podstawowe koncepcje każdej aplikacji opartej na PubNub w mniej niż 5 minut.

Rozpocznij konfigurację
-----------------------

Załóż [konto](https://admin.pubnub.com/signup/) PubNub, aby uzyskać natychmiastowy i bezpłatny dostęp do kluczy PubNub.

Rozpocznij
----------

[Dokumenty](https://www.pubnub.com/docs) PubNub pozwolą Ci rozpocząć pracę, niezależnie od przypadku użycia lub [zestawu SDK](https://www.pubnub.com/docs).