LinuxやWindowsでプロセス間(exe間)で通信をさせる場合や、ある機器間で通信通信させたい場合に
ソケット通信を用いて通信をすることはありませんか?
私は、よくソケット通信を用いて、データの引き渡しを行います。
実は、Pythonでもこのソケット通信を行うことは可能なんです。
そこで今回は、pythonでソケット通信を行う方法について、記載します。
TCP等のソケット通信じゃなくてRawパケットの制御がしたいという人は↓を確認してみてください。
EtherヘッダやIPヘッダ部分を自分でいじれるので以上パケットを投げたいというなニーズに対応できます。
では、まずはServer・Clientの簡単なプログラムを書いてみましたので、以下に記載します。
Serverとは、通信のマスターとなる方で、ClientはServerに接続するものです。
Server側(Server.py)
import socket Portnum = 12345 def create_server(ip,port): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind( (ip,port) ) server.listen() return server if __name__ == '__main__': server = create_server('127.0.0.1',Portnum) (con, client) = server.accept() print("Success connect to client", client) x = bytearray([1, 2, 3, 4]) con.send(x) while(True): data = con.recv(1024) if not data : pass else: con.close() print( data.hex() ) break print("Server finish")
Client側(clietn.py)
import socket Portnum = 12345 def create_client(ip,port): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect( (ip,port) ) return client if __name__ == '__main__': con = create_client('127.0.0.1',Portnum) print("Success connect to Server") while True: data = con.recv(1024) if not data : pass else: print( data.hex() ) x = bytearray([5, 6, 7, 8]) con.send(x) con.close() break print("Client finish")
実行結果は以下の通りです。
Server側
Client側
続いてはプログラムの解説ですが、解説は次ページにて記載します。
ここから解説します。
まず、ソケット通信を行うためには、標準ライブラリのsocketをインポートします。
以下を記載してください。これは、Server・Clientで共通で記載が必要です。
import socket
Server側が簡単にソケット通信を行う場合はざっくりと以下の流れを行います。
①ソケットを生成 ・・ 接続するためのソケットを生成する
②Bind ・・ 生成した ソケット に接続を行うIPアドレスとポート番号を指定する
③Listen ・・ ソケット の待ち受けを開始する。
④Accept ・・ 接続された相手を許可する
今回のサンプルプログラムでは、①から③までを以下の関数で行っています。
def create_server(ip,port): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ① server.bind( (ip,port) ) ② server.listen() ③ return server
①のsocket生成の 第2引数のSOCK_STREAM はTCP通信を用いるという設定です。
ちなみに、 SOCK_STREAM をSOCK_DGRAMに設定すると、UDP通信で通信することになります。
※一般的に、TCP通信はハンドシェイク方式で通信ロストは発生しない方式になりますが相手の応答を待つ必要があり通信が遅くなります。それに対して、UDP通信はデータをドカッと渡す方式になるので、UDPの方が高速な通信になります。
ただし、UDPではデータロスト等が発生する可能性があり、その検出もできません。
なのでUDPを使用する場合は、ユーザー側で何かしらの仕組みを構築する必要があります。。
なので、私は普段、 TCP通信 を使うようにしています。
※UDPでロストしないようにしようとすると、アプリケーションのレベルで何かしらのプロトコルを実装する必要になります。
②のbindで設定しているIPアドレスの127.0.0.1 はローカルのIPアドレスになります。
ローカルIPアドレスとは、同一パソコン内で通信するようのIPアドレスになり、一般的に 127.0.0.1 が
設定されています。
そして、そのあとの以下で、④を行っています。
(con, client) = server.accept() ④
戻り値は2つ応答され、conを用いて通信を行うことになります。
そして、clientには接続先の情報が入ります。
では、実際の送受信処理となりますが、それはそれぞれ以下で行っています。
x = bytearray([1, 2, 3, 4]) con.send(x)
送信は、bytearray側という型のデータをsend関数入れるだけ送出されます。
この場合は、01020304と送信することになります。
data = client.recv(1024)
受信側は、recv関数を受信最大サイズを引数に指定して呼び出すだけ受信できます。
※受信は、ソケット通信の特性として、その時に受信できている分だけのデータを返してくるので、
必ず一つのデータが入るわけではないので注意してください。
複数のデータが連結して通知される場合や、データが足りていないこともあります。
つづいてClientですが、こちらも簡単に接続するための流れを記載します。
ClientはServerよりも単純です。
①ソケットを生成 ・・ 接続するためのソケットを生成する
②connectする ・・ 接続先のIPアドレスとポート番号を指定して接続する。
今回のサンプルプログラムでは、以下の関数で行っています。
def create_client(ip,port): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ① client.connect( (ip,port) ) ② return client
送受信のやり方は、Server側と同様です。
ソケットクローズ処理
あとはソケット通信を行った場合は、以下で最後にソケットを切断してから終了してください。
これはServer・Client共通で必ず行ってから終了してください。
con.close()
今回は、ソケット通信のやり方を記載しましたが、PythonでもWindowsやLinuxと呼び方が違うだけで手順や与える引数はほとんど同じやり方になりました。
これで、作成したプログラム間を通信させて、複雑なことや処理の負荷を分散ができるように設計できるようになりますので、ぜひやってみてください。
負荷分散については、合わせてマルチスレッドのやり方を覚えるとよりよいプログラムをかけるようになりますので、↓の記事も参考にしてみてください。
こちらは、マイクの入力音声をリアルタイムでファイルに出力する方法をまとめた記事になりますが、マルチスレッドの書き方も簡単にですが紹介しています。
Pythonについて勉強したい人は以下がおすすめです。私も持っていてたまに眺めて勉強していますものですのでぜひ購入して学習してみてください。
|