Pythonソケットプログラミング：クライアント、サーバー、ピアライブラリ
Published: 2023-12-11 09:20:20

このチュートリアルでは、Python ソケットプログラミングと Socket API を使ってクライアントとサーバー間でデータを交換する方法を学びます。 後ほど、このチュートリアルではホストされたプロバイダーを使って複数の Python クライアント間で直接データを交換する方法について説明します。 このチュートリアルで使用するソースコードは [GitHub リポジトリ](https://github.com/PubNubDevelopers/python-socket-demo).

ソケットプログラミングは、2つのソケット（クライアントソケットとサーバーソケット）を接続し、リアルタイムで双方向通信を可能にします。 直接ソケット接続は、いつでもデータを送受信できるため、すべてのリアルタイムアプリケーションにメリットがあります。

Pythonはソケットプログラミングに向いていますか？
---------------------------

はい！Pythonにはsocket、select、asyncioなど、クライアントサーバアプリケーションを作成するために必要なモジュールが多数組み込まれているので、ソケットプログラミングに最適です。

### Pythonソケットは何に使うのですか？

Pythonソケットは、Webサーバー、チャットアプリケーション、メールクライアントなど、ネットワーク上で通信する必要があるアプリケーションに使用されます。クライアントがサーバーに接続してデータを送受信する一方で、サーバープログラムはリッスンして着信接続を処理します。Pythonのソケットは、[TCP（](https://www.pubnub.com/guides/tcp-ip/)パケットを順番に確実に配送する信頼性の高いプロトコル）と[UDP（](https://www.pubnub.com/guides/udp/)パケットロスを許容するアプリケーションのためのコネクションレスで軽量なプロトコル）の両方をサポートしています。

### Pythonでソケットプログラムを実行するには？

以下のガイドでは、互いに通信できるPythonクライアントとサーバを作成する手順を説明します。 両方のプログラムを別々に実行する必要があります：

`python myServer.py`

`python myClient.py`

**Python プログラミング** 環境のセットアップ
----------------------------

安定したバージョンの [Python バージョン 3.x](https://www.python.org/downloads/)Windows ユーザーの場合、Python を PATH に追加するオプションがあります。

[Visual Studio Codeは](https://code.visualstudio.com/)、Pythonを含む多くの言語とフレームワークをサポートする、人気のあるオープンソースでフリーのコードエディタです。 VSCodeは、コード補完とデバッグを支援するPython用の拡張機能もサポートしています。

Pythonソケットアプリケーションのビルドと実行
-------------------------

Pythonを使って簡単なソケットアプリケーションを作ってみましょう。Pythonはネイティブの [ソケットクラス](https://docs.python.org/3/library/socket.html)(ソケットモジュール）が用意されているので、外部ライブラリに依存する必要はありません。Pythonソケットプログラミングのクライアントとサーバのセットアップから始めます：

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

### Python ソケットライブラリのインポート

プロジェクトディレクトリにfileclient.pyを作成します。ソケットを使用するために、Pythonソケットライブラリをインポートし、指定されたIPアドレス（ここではポート番号8080のlocalhostですが、任意のIPv4アドレスを選択できます）に接続する新しいソケットオブジェクトを作成します。 ソケットサーバへの新しい接続を作成し、TCPサーバにデータを送信し、ソケット接続を閉じます。

client.pyファイルはこのようになります：

```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())
```

クライアントからの接続とメッセージをリッスンするソケットサーバが必要です。server.pyファイルを作成し、以下の内容を追加します：

```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は、ポート8080のホスト名(localhost)にソケットオブジェクトをバインドし、継続的に新しいクライアント接続を待ち受けます。クライアントがこのアドレスに接続すると、サーバは接続を受け入れ、データを読み込みます。クライアントからのデータの読み込みに成功すると、サーバはデータ応答を返し、その時点でクライアントは接続を終了します。

### Pythonソケットプログラミングのテスト

これを自分でテストするには、ターミナルウィンドウを2つ同時に開きます。 1つのウィンドウで、以下を実行します：

```js
python3 server.py
```

2つ目のウィンドウで

```js
python3 client.py
```

サーバーは実行を続け、クライアントを実行するたびに新しい接続を確立し、新しい出力を追加することに注意してください。

クライアントは "I am CLIENT "文字列をサーバーに送信し、応答を待つ。サーバーはクライアントのメッセージを読み、端末に出力し、クライアントに応答を返します。

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

PubNubを使ったPythonでのソケットプログラミング
-----------------------------

これまで、このチュートリアルではサーバとクライアント間のメッセージ交換について説明してきましたが、Pythonクライアント間で直接通信する必要がある場合はどうすればよいでしょうか？

2つ以上のクライアントデバイス間で直接データを送信するのは、デバイスの数が増えるにつれて多くのスケーリングとセキュリティの考慮事項にぶつかるので厄介です。 クライアント-サーバアーキテクチャは、クライアント間の通信を制御および管理するために使用されます。ウェブサーバーを持っていなかったり、アプリケーションの要求に合わせてサーバーのスケーリングが心配な場合は、次のようなホスト型のリアルタイム通信ソリューションを選ぶべきです。 [PubNub](https://www.pubnub.com/).PubNubはグローバルに分散されたスケーラブルなクラウドプラットフォームなので、サーバーのデプロイや保守を心配する必要はありません。 PubNubのクロスプラットフォームSDKには以下が含まれます。 [Python](https://www.pubnub.com/docs/sdks/python)を含むPubNubのクロスプラットフォームSDKは、ユーザーを識別して特定のチャネルにメッセージを送信し、購読しているクライアントだけが受信できます。

### クライアント間Pythonソケットプログラミング

では、前回紹介したシンプルなアプリをPubNubを使ってどのように書けば、2つのクライアント間で直接メッセージをやり取りできるのだろうか？ PubNubはエンドポイント間で双方向のメッセージを送受信するために「publish」と「subscribe」アーキテクチャ（pub/sub）を使用しているが、裏ではまだソケットを使用していることを理解することが重要だ。PubNubは、Pythonのネットワークプログラミングの詳細を心配することなくソケット通信の利点を提供し、オペレーティングシステムに関係なくクライアント間の常時接続を維持します。

PubNubをプロジェクトに統合するには、ターミナルでpipを使用してPubNubパッケージをインストールします。 [PubNub Python SDK](https://www.pubnub.com/docs/sdks/python)を使用できるようになり、PubNubインフラストラクチャと通信できるようになります。

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

PubNubネットワークに接続して通信するために、2つのクライアントを作成する必要があります。pn\_client\_1.pyファイルを作成し、以下のコードを追加します：

```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.basename(__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 ("from device " + 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)
```

pn\_client\_2.pyファイルを作成し、pn\_client\_1.pyで使用したのと同じコードを追加します。

上記のコードでは 'demo' キーを使用していますが、カスタムの [PubNubキー](https://admin.pubnub.com/#/register)を無料で入手できます。

pn\_client\_1.pyとpn\_client\_2.pyの両方を2つの異なるターミナルウィンドウで同時に実行します。

```js
python3 pn_client_1.py
```

```js
python3 pn_client_2.py
```

各クライアントはPubNubネットワークへの接続を初期化し、新しいメッセージが'chan-1'チャンネルに公開されるたびに受信を申し込む。これはPythonでTCPソケットを使ってデータを送信していると考えることができます。舞台裏では、PubNubがあなたの代わりにソケットを作成して管理し、あなたのメッセージをリッスンしているすべてのクライアントにルーティングしています。リモートクライアントがメッセージを受信すると、受信したメッセージがコマンドラインに表示されます。

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

それだけです！

Pythonでソケットに代わるものは何ですか？
-----------------------

PubNubを使った開発の詳細については、PubNubの様々な [チュートリアル](https://www.pubnub.com/tutorials/)そして [デモ](https://www.pubnub.com/demos/)または [PubNubインタラクティブツアー](https://www.pubnub.com/tour/introduction/)をご覧ください。このプラットフォームがどのようにアプリケーションにリアルタイムのインタラクティブ性を提供するかを理解することができます。PubNubは、Linux、Unix、Windowsだけでなく、TCPおよびUDPデータグラム通信をサポートしています。

Websocketに関する専門家による記事やガイドなど、リアルタイムメッセージングに関する豊富なリソースを用意しています。以下に貴重なリンクをご紹介します。

-   [Websocketとは](https://www.pubnub.com/guides/what-are-websockets-and-when-should-you-use-them/)
    
-   [PubNubリソース](https://www.pubnub.com/resources)
    
-   [PubNubブログ](https://www.pubnub.com/blog/)
    

PubNubはどのようにお役に立ちますか？
=====================

この記事は[PubNub.comに](https://pubnub.com/blog/socket-programming-in-python-client-server-p2p/)掲載されたものです。

PubNubのプラットフォームは、開発者がWebアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるよう支援します。

私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイムエッジメッセージングネットワークです。世界15か所以上で8億人の月間アクティブユーザーをサポートし、99.999%の信頼性を誇るため、停電や同時実行数の制限、トラフィックの急増による遅延の問題を心配する必要はありません。

PubNubを体験
---------

[ライブツアーを](https://www.pubnub.com/tour/introduction/)チェックして、5分以内にすべてのPubNub搭載アプリの背後にある本質的な概念を理解する

セットアップ
------

[PubNubアカウントに](https://admin.pubnub.com/signup/)サインアップすると、PubNubキーに無料ですぐにアクセスできます。

始める
---

[PubNubのドキュメントは](https://www.pubnub.com/docs)、ユースケースや[SDKに](https://www.pubnub.com/docs)関係なく、あなたを立ち上げ、実行することができます。