今回は、最初から最後まで、Pythonでチャットルームを作成します。
その前に、チャットルームとは何かということを概念的に理解しておきましょう。
チャットルームとは?
チャットルームは、世界中の人々が様々なトピックについてコミュニケーションをとることができるスペースです。
話題はアプリの開発から、キッチンで作ったレシピまで何でもありです。
チャットルームは、コミュニケーションの取り方を学ぶのに最適なプラットフォームです。
この記事では、ソケットとpythonを使った基本的なコンセプトで、小さなチャットルームを作る方法を紹介します。
さて、この記事では、pythonでsocketを使ったリアルタイムチャットアプリを構築します。
まず、ソケットの概念から説明します。
ソケットとは?
ソケットとは、ネットワーク用語で、TCP/IPプロトコルスイートにおいて、アプリケーション層とトランスポート層をつなぐ中間的な役割を果たすものです。
このネットワークソケットは、クライアント側とサーバー側に存在します。
ソケットプログラミングは、ネットワーク上の2つのノードが互いに通信できるように接続する方法です。
あるソケット(ノード)はIPの特定のポートでリッスンし、別のソケットはもう一方に手を伸ばして接続を形成します。
サーバーはリスナーソケットを形成し、クライアントはサーバーに手を伸ばします。
import socket
import sys
import time
|
チャットルーム サーバーサイド ソケット プログラミング
サーバはクライアントからの接続を受け付け、ネットワークインタフェースを確立します。
クライアント/ユーザが一意であることを保証する必要があります。
そのため、各クライアントに一意のIPアドレスを割り当てます。
しかし、多くのユーザーはユーザー名で識別されることを好みます。
従って、ユーザー名も同様に割り当てます。
サーバーの役割は、受信したメッセージを収集し、他のクライアント/クライアントに配信することです。
では、サーバサイドのコーディングを始めましょう。
まず、server.py
という名前のファイルを作成します。
1. 必要なライブラリのインポート
new_socket = socket.socket()
host_name = socket.gethostname()
s_ip = socket.gethostbyname(host_name)
port = 8080
|
まず、ソケットを実装するために必要な関数が含まれている socket
ライブラリをインポートします。
sys` ライブラリは、システムディレクトリ、関数、およびメソッドに関連するデータを提供する責任を負う、システムモジュールを提供します。
time` モジュールは、時間の変換や記述に関する多くのアクションを実行できるようにします。
2. ソケットの作成とホスト名の取得
new_socket.bind((host_name, port)) print ( "Binding successful!”)
print ( "This is your IP: " , s_ip)
|
socket()`関数は、ソケットを作成するためのソケットライブラリのコンストラクタです。
ソケットが生成されたら、ホスト名/デバイス名を gethostname()
で取得します。
gethostname()に
host_nameを指定して送信すると、相手のIPアドレスを取得し、このIPアドレスは
s_ip` に格納される。
port` には 8080 が指定される。
このポートが選ばれた理由は、ほとんどのマシンでデフォルトで使用されていないポートだからです。
一般に、3000や5000などのポートは、express.jsのような他のアプリケーションに使用されます。
1234’などの任意のポートで実行することもできます。
3. ホストとポートのバインド
name = input ( 'Enter name:' )
new_socket.listen( 1 )
|
ソケットオブジェクト new_socket
に対して呼び出される bind 関数を用いて、ホストとポートをバインドします。
バインドに成功すると、コンソールに “Binding successful!” と表示されます。
4. コネクションを聴く
conn, add = new_socket.accept()
print ( "Received connection from " , add[ 0 ])
print ( 'Connection Established. Connected From: ' ,add[ 0 ])
|
ここでは、listen()
関数を使用します。
この関数は number_of_connections
という 1 つの引数を受け取ります。
この引数には、1,2,3,…のような任意の整数を指定することができます。
この記事もチェック:Pythonのrandint関数の使い方|引数や範囲指定のやり方を解説
5. 着信接続を受け入れる
client = (conn.recv( 1024 )).decode()
print (client + ' has connected.' )
conn.send(name.encode()) |
最初の変数 conn
がソケットに接続され、変数 ‘add’ がクライアントの IP アドレスに割り当てられます。
6. 着信接続データの保存
while True :
message = input ( 'Me : ' )
conn.send(message.encode())
message = conn.recv( 1024 )
message = message.decode()
print (client, ':' , message)
|
受信した接続の詳細は、client_name 変数に格納される。
クライアント名は最大1024バイトです。
サーバでデコードされ、接続された旨のメッセージが表示される。
その後、サーバはホスト名を送信します。
7. パケット/メッセージの配送
import time, socket, sys
new_socket = socket.socket()
host_name = socket.gethostname()
s_ip = socket.gethostbyname(host_name)
port = 8080
new_socket.bind((host_name, port)) print ( "Binding successful!”)
print ( "This is your IP: " , s_ip)
name = input ( 'Enter name: ' )
new_socket.listen( 1 )
conn, add = new_socket.accept()
print ( "Received connection from " , add[ 0 ])
print ( 'Connection Established. Connected From: ' ,add[ 0 ])
client = (conn.recv( 1024 )).decode()
print (client + ' has connected.' )
conn.send(name.encode()) while True :
message = input ( 'Me : ' )
conn.send(message.encode())
message = conn.recv( 1024 )
message = message.decode()
print (client, ':' , message)
|
ユーザはメッセージを入力します。
このメッセージは encode()
によってエンコードされ、ソケットを介して送信されます。
メッセージの送信は、先ほどの accept() 関数の呼び出しで生成されたコネクションオブジェクト上で send()
関数を用いて行われます。
そして、”message has been sent… “と表示されます。
受信したメッセージは conn オブジェクトの recv()
を使って受信します。
最大で1024バイトの情報を受信することができます。
メッセージはサーバ側で decode()
を用いて復号されます。
この記事もチェック:Pythonでinput関数を使ってユーザーからの標準入力を変数に格納する方法
サーバーサイドのチャットルームの完全なコード
サーバーサイドのチャットルームの完全なコードです。
import socket
import sys
import time
|
socket_server = socket.socket()
server_host = socket.gethostname()
ip = socket.gethostbyname(server_host)
sport = 8080
|
チャットルーム クライアントサイドソケットプログラミング
client.py というファイルを作成し、チャットサーバに接続し通信するためのコードを作成します。
1. ライブラリのインポート
print ( 'This is your IP address: ' , ip)
server_host = input ( 'Enter friend's IP address:' )
name = input ( 'Enter Friend's name: ' )
socket_server.connect((server_host, sport)) |
サーバ側で使用しているライブラリをインポートします。
2. ソケットの作成とユーザ入力の受付 ホスト名
socket_server.send(name.encode()) server_name = socket_server.recv( 1024 )
server_name = server_name.decode()
print (server_name, ' has joined...' )
while True :
message = (socket_server.recv( 1024 )).decode()
print (server_name, ":" , message)
message = input ( "Me : " )
socket_server.send(message.encode())
|
- サーバ側のソケットは
socket()
メソッドで生成される。 - サーバーのホスト名はクライアント側で取得し、
server_host
として保存される。 - IP アドレスは
ip
に格納される。 - サーバーのポート番号は 8080 として
sport
変数に格納される。
このポートは、サーバサイドのコードに記載されているポートと一致しなければならないことに注意すること。
3. サーバーへの接続
import time, socket, sys
socket_server = socket.socket()
server_host = socket.gethostname()
ip = socket.gethostbyname(server_host)
sport = 8080
print ( 'This is your IP address: ' ,ip)
server_host = input ( 'Enter friend's IP address:' )
name = input ( 'Enter Friend's name: ' )
socket_server.connect((server_host, sport)) socket_server.send(name.encode()) server_name = socket_server.recv( 1024 )
server_name = server_name.decode()
print (server_name, ' has joined...' )
while True :
message = (socket_server.recv( 1024 )).decode()
print (server_name, ":" , message)
message = input ( "Me : " )
socket_server.send(message.encode())
|
最初にサーバー(友人)の詳細を入力します。
IPアドレスは正確に入力しないと通信に失敗しますので注意してください。
サーバーのホスト名とポートをある方法で結合し、ソケットに接続します。
4. サーバーからのパケット/メッセージの受信
メッセージを受信するために、socket_serverはrecv()関数を呼び出して1024個のデータを受信します。
メッセージオブジェクトに格納され、decode()関数でデコードされる。
メッセージには、サーバのホスト名と受信したメッセージが表示されます。
クライアントは、任意のメッセージを入力として入力し、同じようにエンコードして、ソケットを使ってサーバーに送信することができます。
このように、ソケットとpythonを使用してリアルタイムチャットルームを展開しました。
この記事もチェック:Python HttpServerを簡易HTTPサーバーとして使用する方法
完全なクライアントサイドチャットルームコード
以下は、チャットルームのクライアントサイドの完全なコードです。
まとめ
完全なコードスニペットをコピーして、それぞれ server.py と client.py として保存すれば、Python で初めてのチャットルームが完成します! これはとても簡単で、ソケットプログラミングの実用的な面をたくさん学ぶことができると思います。