Python socket ソケット通信

Python学習【365日チャレンジ!】163日目のマスターU(@Udemy11)です。

物欲が収まったと思ったら、釣りに行きたい欲が湧いてきて困ってしまいます。

釣れまくってたのし〜!

ってなるくらい釣れるといいんですが、気合を入れて準備万全で釣りに行くと、まったくもって肩透かしを食らってしまいます。

かといって、今日は小物釣りだからネットはいらないかなと思って適当な道具だけ持っていくと、大きいのが釣れてバラしちゃうんですよね。

ほんと、釣りって難しいですね。

ま〜、そんなところがハマってしまう原因なんでしょうけど。。。

それでは今日もPython学習を始めましょう。

昨日の復習

昨日は、socketを使ってサーバーとクライアントのやり取りを学習しました。

Pycharmの画面を2つに分けて、サーバーとクライアントのファイルを作成し、サーバーは接続待ちの状態にして、クライアント側から接続してみました。

詳細については、下記の記事をごらんください。

今日は、socketを使って、UDPでやり取りをしてみたいとおもいます。

Pycharmの準備

昨日同様に、Pycharmを2画面にしてサーバー側とクライアント側のコードを書いて、ターミナルで動作を確認します。

Python socket ソケット通信

ファイルタブの右クリックから【Split Vertically】で画面を2つに分けてサーバー側とクライアント側のファイルを表示します。

ターミナルも同様に画面を分けておきましょう。

Pycharmで指定できるインタプリタは1つなので、ファイルはターミナルから実行します。

サーバー側コード

サーバー側のコードを書いていきましょう。

import socket


with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
    s.bind('127.0.0.1', 50007)
    while True:
        data, addr = conn.recvfrom(1024)
        print('data: {}, addr: {}'.format(data, addr))

socketパッケージをインポートするのは、TCPのときと一緒です。

4行目でwithステートメントを使ってsocketを開くのは同じですが、アドレスファミリーはAF_INETでTCPのときと同じですが、ソケットタイプは、UDP接続に対応したSOCK_DGRAMを指定します。

アドレスファミリーやソケットタイプの解説については、Python公式ドキュメントをごらんください。

TCPのときと同じようにs.bind()は必要ですが、クライアントの接続待ちのためのs.listens.accept()は不要です。

6行目以降は、クライアント接続時の処理で、Whileループで、受け取ったデータを直接dataaddrに、代入し、8行目でコンソールに受け取ったデータとアドレスを表示しています。

s.recvfrom()の引数1024は、受け取るデータの最大値になります。

クライアント側コード

クライアント側のコードもTCPと違ってかなりシンプルです。

import socket


with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
    s.sendto(b'Hello This is UDP connection.', ('127.0.0.1', 50007))

サーバー側と同様にsocketパッケージをインポートします。

4行目は、サーバー側のコードと同じく、第2引数をsocket.SOCK.DGRAMにしています。

5行目で、s.sendto()を使って、バイトデータのHello This is UDP connection.とIPアドレス、ポートを送信するだけです。

実際の動き

これまた非常に短いですが、UDPで通信した動画を作っていました。

TCPのときと同じく、サーバー側はクライアント側の接続を待っている状態になり、クライアント側のファイルを実行すると、サーバー側で受け取ったデータを表示します。

UDPでも、データを受け取ったあとにクライアントに処理を返すことはできるようですが、テレビやラジオ同様にレスポンスを受け取るわけではなく、ストリーミング配信などのデータ投げっぱなし処理に向いているということです。

どちらを優先するか

TCPは、データがきちんとサーバーに届いたかを確認するので、信頼性が高い一方で、1対1のやり取りしかできません。
UDPは、データはサーバーに届いたかどうかは別として、迅速にデータを送信し、あとは確認する必要がありませんし、複数にデータを送ることができます。

データが届いているかどうかの確認が必要な場合は、当然のことなら、TCPを使った通信が最適です。
しかし、ストリーミングなどであれば、失敗していてもあまり問題はないので、リアルタイム性を重視して、UDPが使われています。

適材適所という言葉があるように、必要に応じた規格なりシステムを使うようにしましょう。

それでは、明日もGood Python!