Select Language

AI Technology Community

9.3、TCP echoサーバーの構築(Python実装)

この節では、簡単な echo サーバーを作成します。このサーバーはユーザーの接続を待ち、接続に成功すると、受け取ったユーザーの入力をそのままクライアントに返送します。ユーザーが接続を閉じるまでこれを繰り返し、接続が閉じられるとサーバーは自動的に終了します。

この例では TCP プロトコルを使用しています。使用するプロトコルは、socket を作成する際に指定します。方法は以下の通りです。

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

最初の引数 socket.AF_INET は TCP/IP プロトコルファミリを使用することを表し、2 番目の引数 socket.SOCK_STREAM は UDP ではなく TCP を使用することを表します。

サーバー側ではポート 50007 を使用します。サーバーにとってポートは決まっている必要があります。ポートが決まっていないと、クライアントはメッセージをどこに送信すればいいか分からなくなります。IP アドレスは記入しなくても構いません。なぜなら、プログラムはオペレーティングシステムから自身の IP アドレス情報を取得することができるからです。サーバーが使用するポートと IP アドレスを決定するには bind() を使用します。

s.bind((HOST, PORT))


listen() 関数はクライアントの接続を待つために使用されます。一般的には、サーバーは最初に起動され、クライアントからの接続要求があるまで待機状態になります。

s.listen(10)

引数の 10 は待ち行列の長さが 10 であることを表します。つまり、同時に 12 個のクライアントから接続要求があった場合、11 番目と 12 番目の要求は拒否されます。これらの拒否されたクライアントの connect() 関数は失敗情報を返します。

accept() 関数はクライアントの接続要求を受け取るために使用されます。この関数はクライアントの IP アドレスとポート番号の情報を返し、新しい socket オブジェクトも返します。

conn, addr = s.accept()


accept() が返す新しい socket オブジェクトを使用すると、データの読み取りと書き込みができます。データを読み取ることは、クライアントから送信されたデータを取得することに相当し、データを書き込むことは、クライアントにデータを送信することに相当します。

data = conn.recv(1024)
conn.sendall(data)

データを読み取る際にはキャッシュサイズを指定することができます。つまり、クライアントが大量のデータを送信した場合、複数回に分けて読み取ることができ、1 回に読み取る最大バイト数を指定することができます。上の例では、現在の最大読み取りバイト数を 1024 バイトに指定しています。クライアントが送信するデータが 1024B を超える場合、複数回に分けて読み取る必要があります。

最後に、リソースを解放するために socket を閉じます。サーバーには 2 つの socket があります。1 つは接続要求を受け取るためのもので、もう 1 つはデータを送信するためのものです。そのため、以下の 2 つの閉じる文があることがわかります。

conn.close()
s.close()


以下は完全なコードです。

import socket                    # 使用するsocketインターフェース
HOST = ''                         # ローカルアドレスとポート
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # socketを作成
s.bind((HOST, PORT))            # ローカルIPとポートにバインド
s.listen(10)                    # ユーザーの接続要求を待つ
conn, addr = s.accept()            # ユーザーの接続要求を受け取る
print('Connected From', addr)    # ユーザーのアドレス情報を表示
while True:                        # ユーザーのデータを受け取り、そのまま返す
    data = conn.recv(1024)        # データを読み取る
    if not data:                 # 読み取りに失敗した場合、例えばユーザーが接続を閉じた場合
        break                    # ループを抜ける
    conn.send(data)                # 受け取ったデータをユーザーに返す
conn.close()                    # データの読み書き用の接続を閉じる
s.close()                        # 接続要求用のsocketを閉じる


post
  • 5

    item of content
初期には、コンピュータ同士は相互に接続されておらず、孤立していました。それらの間のデータ交換は主にフロッピーディスク(現在のUSBフラッシュドライブに相当)を通じて行われていました。その後、人々はネットワークを創造し、コンピュータ間で情報の交換が可能になりました。
初期のコンピュータネットワークも種類が豊富で、サポートされているプロトコルも多岐にわたっていました。時間の経過とともに、現在広く使用されているのはIPネットワークとなり、他のタイプのネットワークは次第に姿を消しました。現在、オフィス内のローカルエリアネットワークでもインターネットでも、基本的にはIPネットワークを使用しています。
この章では、Pythonのネットワークプログラミングに関する知識を読者に紹介します。具体的には、TCP/IPプロトコル、ソケットインターフェース、TCP/UDPクライアントおよびサーバーの構築方法などを含みます。