Engineering Note

プログラミングなどの技術的なメモ

2.3 UDPクライアント (サイバーセキュリティプログラミング Pythonで学ぶハッカーの思考)

本記事は、オライリージャパンから発行されている「サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考(原題:Black Hat Python)」の学習メモとして、書籍ではPython2で書かれていますが、自分なりに解釈した上でPython3に書き直しをしています。

今回はPythonのsocketモジュールを使用したUDP通信(クライアント)の基本について学んでいきます。

 

 

UDPクライアントの実装

前回ではTCPクライアントの実装について学びました。

engineeringnote.hateblo.jp

今回のUDP通信についても、前回と同様にPythonのsocketモジュールを用いて実装をしていきます。

以下が今回のコードになります。

 

# udp_client.py
import socket

buf_size = 4096
target_host = "127.0.0.1"
target_port = 8000

soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

soc.sendto(b"this is a test message.", (target_host, target_port))
data, addr = soc.recvfrom(buf_size)

print("[*] Received:{} from {}:{}".format(data.decode('utf-8').strip(), addr[0], addr[1]))

 

socketの生成

8行目でsocketを生成します。

"AF_INET"はアドレスファミリ(Address Family)と呼ばれるネットワークの種類を表すもので、"AF_INET"はIPv4を意味し、AF_INET6はIPv6を意味します。

インターネット上では、基本的にはまだIPv4が主流なので、"AF_INET"を指定しています。

また"SOCK_DGRAM"はUDPを使用することを指定しています(TCPの場合は"SOCK_STREAM"を指定します)。

 

データ送信

UDPコネクションレス型のプロトコルになります。

TCPの際は、データ送受信の前にconnect()を呼び出し、通信を行う準備(3 Way Handshake)をしていましたが、UDPの場合はいきなりデータを送信します。

10行目のsendto()を呼び出し、データおよび送信先アドレスとポート番号をタプルにした引数を指定します。

なお、Python2では文字列とバイト列が区別されていないため、データの送受信はそのまま文字列としていましたが、Python3ではバイト列としなければなりません。

 

データ受信

11行目で、サーバからのデータを受信します。

受信データは、bytesオブジェクトおよびタプルされた送信元(サーバ)のアドレスとポート番号が、タプルとして返されます。

socketオブジェクトからrecvfrom()で指定したバッファサイズを読み取り、このバッファサイズは基本的に2の累乗の値を指定します(ここでは4096byteを指定)。

 

レスポンスの表示

13行目でサーバからのレスポンスを表示しています。

"data"はbytesオブジェクトの為、decode()でstr型に変換し、strip()で改行("\n")を取り除いています。

"addr"には、サーバのアドレスとポート番号がタプルで格納されているので、それぞれインデックスを使用して表示しています。

 

データ送受信を行ってみる

WSLのUbuntu上でnc(netcat)コマンドを実行し、簡易UDPサーバを起動します。

なお、echoコマンドにパイプしてあげると、接続してきたクライアントにメッセージを送信することができます。

そして、コマンドプロンプトからPythonスクリプトを実行すると、以下のメッセージが送受信されます。

 

 # server
> echo "OK!" | nc -ul 8000
this is a test message.

# client
> python udp_client.py
[*] Received:OK! from 127.0.0.1:8000

 

最後に

以上がUDPクライアントをPythonで実装したものになります。

UDPTCPのような信頼性や順序性、またデータ完全性が保証されていない分、オーバーヘッドも少なく、そのヘッダ構造もとてもシンプルなものとなっています。

次回はサーバの実装について学んでいきます。

 

参考書籍

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考