9
5

More than 1 year has passed since last update.

ESP32同士でsocket通信をしたい

実装がかなり大変だったため,備忘録として.

はじめに:ソケット通信って?

他の方で非常に良い記事がありましたのでそちらを参照ください.
https://qiita.com/megadreams14/items/32a3eed4661e55419e1c

プログラム:何はともあれまずはソースコード

環境:

>>> os.uname()
(sysname='esp32', nodename='esp32', release='1.17.0', version='v1.17 on 2021-09-02', machine='ESP32 module with ESP32')

TCPサーバ

server.py
import socket #モジュールのインポート

port = 80 #ポート指定
listenSocket = None #初期化


ip = wifi.ifconfig()[0] #自分のipアドレスを取得
listenSocket = socket.socket() #socketを作成
listenSocket.bind((ip, port)) # ソケットを特定のIPアドレスとポートに紐付け
listenSocket.listen(5) # 接続の待受を開始
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,  1) #指定されたソケットオプションの値を設定

while True:
    print("accepting.....") 
    conn, addr = listenSocket.accept() #接続を受信
    print(addr, "connected") #接続した相手のipアドレスを表示 (xxx.xxx.xxx.xxx connected)

    while True:
        data = conn.recv(1024) #一度に受け取るデータのサイズを指定
        if(len(data) == 0):
            print("close socket")
            conn.close() #接続を切断
            break
        print(data)

TCPクライアント

client.py
import socket              

s = socket.socket() #ソケットの作成
host = '192.168.0.18' #接続先のipアドレス
port = 80 #ポート指定

s.connect(socket.getaddrinfo(host, port)[0][-1]) #接続確立

if __name__ == '__main__':
    while True:
        msg = input('--->>> ') 
        s.sendall(msg) #入力された文字列を送信

実際に動作させてみる

先にサーバ側のプログラムを実行させ,ソケットの待受を開始する.

・クライアント側
image.png

・サーバ側
image.png

こんな感じでクライアント側で入力した文字列がサーバ側でリアルタイムで確認できるようになる.

ソースコード:解説していくよ

TCPサーバ

micropythonにはソケット通信を行うためのモジュールが標準的に組み込まれています.
解説はmicropythonの公式ドキュメントを参照しつつ行います.


listenSocket = socket.socket() #socketを作成

image.png

簡単に言えばここでソケットを生成します.オプションも付けられます.


listenSocket.bind((ip, port)) # ソケットを特定のIPアドレスとポートに紐付け

image.png

ソケットを特定のIPアドレスとポートに紐付けます.
引数addressと書いてありますが,ソースコード例のようにタプルで指定しないとダメです.
基本的にはIPアドレスとポートを渡せばOK


listenSocket.listen(5) # 接続の待受を開始

image.png

接続の待ち受けを設定します.
接続可能数を指定します.今回の場合では最大で5接続まで行えます.


listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #指定されたソケットオプションの値を設定

image.png

ここが結構めんどくさい
ドキュメントに書いてある通りですが,引数のlevelとoptnameがチップボードによって異なるため,使うボードによって確認が必要です.

https://docs.micropython.org/en/latest/reference/glossary.html#term-MicroPython-port

image.png
↑参照


conn, addr = listenSocket.accept() #接続を受信

image.png

書いてある通りですが,戻り値はconnとaddressの2つです.
connは接続でデータを送受信するために使用できる新しいソケットオブジェクト.
addressは接続のもう一方の端のソケットにバインドされたアドレス.


data = conn.recv(1024) #一度に受け取るデータのサイズを指定

image.png

たまたまpythonの公式ドキュメントで見つけたんですが,こんなものがありました

注釈 ハードウェアおよびネットワークの現実に最大限マッチするように、 bufsize の値は比較的小さい2の累乗、たとえば 4096、にすべきです。

ということですので,$2^{10} = 1024$でひとまず設定しておきます.(もっと小さくてもいいと思います)


conn.close() #接続を切断

image.png

接続を切断します.


TCPクライアント

s.connect(socket.getaddrinfo(host, port)[0][-1]) #接続確立

image.png

と簡単に書いてあったのですが,,,

image.png

よくよく読むと,こうやって使ってね,と推奨されるやり方があったのでこれを真似しました.


s.sendall(msg) #入力された文字列を送信

image.png

ソケットにデータを送信する.

おわりに

公式ドキュメント,
英語だけどめげずに読むことが大切だということですね

9
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5