Python クライアントサーバソケット機能 UDPプロトコル編(anaconda-jupyter)
UDPプロトコルは、送信するデータの信頼性より送信速度を上げるプロトコルです。
テレビ会議などで動画や音声などのデータを送信するのに使われています。
動画や音声はデータ送信時に多少データが欠落しても問題ないからです。
(動画が少しずれても、音声が少し聞きづらくても、きっと人間は頭の中で修正するからダイジョブなのですね。)
今回は単純なテキストデータをanaconda-jupyterの環境を利用して、python3言語で簡単に「クライアント」と「サーバ」の機能をソケット通信を利用して構築し、通信の方法を確認したいと思います。
anacondaの開発環境の作成はこちらから
UDPとは
UDP (User Datagram Protocol) はトランスポート層で動作するデータを確実に送信するプロトコルです。
機能としては、ただデータを送るだけの機能でデータの欠落などは無視して送信スピードを重視します。
通信方法は「マルチキャスト」と「ブロードキャスト」があります。
マルチキャスト
テレビ会議を想像してもらうと分かりやすいと思います。
マルチキャストとは、複数のクライアントがサーバーのアドレスを指定してクライアントとサーバーがn対1でデータを通信します。
ブロードキャスト
同じネットワーク内の全宛先を指定し、1対不特定多数でデータを通信します。
UDPフラッド攻撃というDoS攻撃に利用されています。
クライアントサーバの確認方法
今回は、自分のパソコン内での通信になるので気兼ねなく、好き放題テストしてください。
anacondaからjupyterを起動して、クライアントのプログラムとサーバのプログラムを登録します。
そして、サーバのプログラムを起動して、次にクライアントのプログラムを起動して通信の機能を確認します。
ソースにはわかりやすくコメントを入れて、命令実行ごとにprint文でアウトプットを表示しています。
ソースの簡単な説明
サーバを起動して、クライアントと通信が繋がるごとにクライアントにサーバからのメッセージを表示します。
Server accessed.(1) 通信1回目のメッセージ
Server accessed.(2) 通信2回目のメッセージ
Server accessed.(3) 通信3回目のメッセージ
: :
ソケット-サーバ機能(003)
サーバ機能のプログラムです。
説明はプログラム内のコメントを参照してください。
# ******************************
# ソケット-サーバ機能(003)
# ******************************
# モジュールのインポート
# 低水準ネットワークインターフェース
import socket
# グローバル変数
# ダイナミックポート番号(49152~65535)
D_PORT_NO = 49152
# 受信バッファの大きさ
BUFSIZE = 4096
# クライアントアクセス回数
access_cnt = 0
# ソケットの作成
# AF_INET:ネットワーク層はIPv4を利用
# SOCK_DGRAM:UDPプロトコルを利用する
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 接続させたいホスト名(またはアドレス)とポート番号を設定
server.bind(("127.0.0.1", D_PORT_NO))
print("サーバ起動しました。クライアントの接続待ち")
# クライアントへの対応処理
while True:
# クライアントからのメッセージ待ち
data, client = server.recvfrom(BUFSIZE)
access_cnt += 1
sending_message = "Server accessed.(" + str(access_cnt) + ")"
print("送信メッセージ=",sending_message)
# クライアントへメッセージの送信
server.sendto(sending_message.encode("utf-8"), client)
print("メッセージ送信完了")
ソケット-クライアント機能(004)
クライアント機能のプログラムです。
説明はプログラム内のコメントを参照してください。
# ******************************
# ソケット-クライアント機能(004)
# UDPクライアント
# ******************************
# モジュールのインポート
import socket
# グローバル変数
# 接続先ホストの名前(localhost)
HOST = "127.0.0.1"
# サーバ側のダイナミックポート番号(49152~65535)
D_PORT_NO = 49152
# 受信バッファの大きさ
BUFSIZE = 4096
# ソケットの作成
# AF_INET:ネットワーク層はIPv4を利用
# SOCK_DGRAM:UDPプロトコルを利用する
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print("client=", client)
print("ソケットの作成")
# サーバとの接続
# "Hello"の文字列をサーバに送信する
client.sendto(b"Hello.", (HOST, D_PORT_NO))
print("サーバにメッセージ送信")
# サーバからのメッセージの受信
server_reception_data = client.recv(BUFSIZE)
print("サーバからの受信データ",server_reception_data.decode("UTF-8"))
#サーバの接続を切断
client.close()
print("サーバ切断完了")
クライアントサーバのテスト
各々のプログラムの実行結果を確認してください。
1.jupyterの「サーバ」のソースの上部メニューの「RUN」ボタンを押下します。
立ち上がるとサーバ側のアウトプットに
サーバ起動しました。クライアントの接続待ち
が表示されます。
2.jupyterの「クライアント」のソースの上部メニューの「RUN」ボタンを押下します。
立ち上がるとクラアインと側のアウトプットに
client= <socket.socket fd=1344, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0>
ソケットの作成
サーバにメッセージ送信
サーバからの受信データ Server accessed.(1)
サーバ切断完了
3.サーバ側のアウトプットには
送信メッセージ= Server accessed.(1)
メッセージ送信完了
これで、サーバとクライアントの通信ができました。
再度クライアントを実行すると
送信メッセージ= Server accessed.(2)
が表示されます。
Python クライアントサーバソケット機能 UDPプロトコル編(anaconda-jupyter)のまとめ
クライアントサーバソケット機能 TCP編を流用しているので動きは同じになりますが、使っている命令が異なります。
UDPのプロトコルを利用する機会は少ないと思いますが、UDPフラッド攻撃に利用されているとのことです。
ぜひ、上記のプログラムを自分流に改良して自分の疑問を解決してくださいね。
ソケット通信の方法やpythonの言語の理解が出来るとおもいます。