C言語でソケット通信

漸くC言語でクライアント・サーバなソケット通信プログラムのサンプルが動いた。

ネット上のサンプルと、微妙にヘッダファイルの名前やパスが違っていて手こずった。

 

これで、C/C++/python の3言語で、それぞれクライアントとサーバのサンプルが動いたことになる。

あ、そういえばあと nc(netcat)によるクライアント・サーバもあった(^^)

 

本番は、サーバ側はC++または python, クライアント側は C言語になる予定。その理由は、サーバ側は

を想定している。

クライアント側は IoT なデバイスとして

  • ESP32
  • ESP8266(WROOM-02)
  • RasPi Zero W
  • mbed(Nucreo) + ESP8266

といったものを想定している。なので、クライアント側はほぼC言語、サーバ側はなんでもありだ。

本来は、送受信するデータ構造の設計が必要。ネットワークバイトオーダや、構造体のパディングなどを考慮して、送信データにするための変換処理が必要。

 

  1. 固定長文字列
  2. 構造体
  3. ヘッダ(データサイズ)
  4. データの欠損/破壊等の検出用フラグ

など、真面目に考えると大変。可変長に対応するとか、ヘッダの構造が複雑になる。

nc(netcat) on ubuntu

サーバ・クライアント間のソケット通信サンプルプログラムの動作確認などに便利なコマンドを発見。

とゆーか、以前見かけたことがあるので再発見である。かなり便利そうなので、使いながら覚えていきたい。

すこし汎用的な Makefile

比較的簡単なプロジェクト用に Makefile のテンプレートを作った。

ソースファイルとオブジェクトファイルのディレクトリを分けたところが、少し工夫したところ。

とはいえ、昔は階層化 Make まで頑張って対応していたので、あくまで簡易版。

# Directories
SRCDIR = ./sources
OBJDIR = ./objs

TARGET =
SRCS = $(wildcard ${SRCDIR}/*.cpp)
OBJS = $(addprefix ${OBJDIR}/, $(notdir $(SRCS:.cpp=.o)))
DEPS = $(addprefix ${OBJDIR}/, $(notdir $(SRCS:.cpp=.d)))

# for preprocesser
INCLUDES =
CPPFLAGS =

# for C++ compiler
CXX = g++
CXXFLAGS = -g -Wall -MMD -MP

# for linker
LD = ${CXX}
LIBDIRS =
LIBS =
LDFLAGS = ${LIBDIRS} ${LIBS}

all: clean ${TARGET}

${TARGET}: ${OBJS}
${LD} -o $@ $^ ${LDFLAGS}

${OBJDIR}/%.o: ${SRCDIR}/%.cpp
@[ -d ${OBJDIR} ]
${CXX} ${CXXFLAGS} -o $@ -c $<

.PHONY: all clean

clean:
${RM} ${TARGET} ${OBJS} ${DEPS}

-include ${DEPS}

 

 

【ESP32】Boost.asio を使ったソケット通信

ubuntu への boost のインストール

boost のパッケージがリポジトリにあるかどうか探した。

$ sudo apt-cache search boost

たくさん見つかった。おそらく最新版ではなく結構古いバージョンだと思われるが、標準でサポートされているのが安心。自分でビルドすると、バージョンアップが大変だから。

インストールの仕方をググり、以下のようにインストールした。

$ sudo apt install libboost-dev libboost-tools-dev

 参考URL:

boostのインストール - C++入門

 boost::asio を使った同期通信

boostjp.github.io

Boost.Asioによる同期接続処理 - C++入門

boost のチュートリアルを発見。

Tutorial - 1.63.0

 

ビルドしてみると、

上記のコマンドでは Boost:asio はインストールされないことがわかった。さらにググったところ、

$ sudo apt search libasio-dev

libasio-dev/xenial,xenial 1:1/10.6-3 all

 パッケージが存在することがわかったので

 $ sudo apt install libasio-dev

でインストールした。

 これでもまだリンクエラーになった。

$ g++ -Wall client_2.cpp 

libboost_system の unreference deference エラーになる。ググったところ、

 -lboost_system をつけるという記事を発見。これでもだめで、さらに

$ ln -s /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 /usr/lib/x86_64-linux-gnu/libboost_system.so

$ g++ -Wall client_2.cpp -L/usr/lib/x86_64-linux-gnu -lboost_system

 

これでリンクエラーがなくなった。

【ESP32】ソケット通信のお勉強

ESP32の特長は、WiFiBluetooth を安価(チップは800円、ボードで1600円)で使えること。しかも、ROM/RAMはArduino(AVRMega386)より多いこと。

 

マイコンとしてのペリフェラルも充実している。ペリフェラルのサンプルコードも公開されているので後で試す。

WiFibluetoothについてサンプルコードを試したいところ。

WiFiについては、ルータに接続するまでのサンプルみたい。 SSID, キー、IPアドレスを指定すると接続に成功する、というサンプル。

 

接続後、 UART 通信のように、データの送信・受信をするサンプルコードを作りたい。

そのためには。TCP/IP の世界で通信の最初のサンプルといえば、ソケット通信だろう。

BSD ソケットであって WebSocket ではない。ブラウザも HTTP も関係ない、ソケット通信。

手順としては、PC上で以下のサンプルコードを作成する。

  1. C++で、サーバ/クライアントのソケット通信
  2. pythonでサーバ/クライアントのソケット通信
  3. C++ <==>python でサーバ/クライアントのソケット通信

を行う。これだけ準備をしてから、 ESP32DevKitC とPCでサーバ/クライアントソケット通信を行う。 ESP32側は C++, PC側は Python or C++ になる。

 

【ESP32】HelloWorld まで成功!

Windows10上の MinGW+MSYS や Cygwin だと、微妙にエラーが出てしまった。

VirtualBox 上の Ubuntu で環境構築を試みたところ、サンプルプロジェクトのビルドまではできるのだが、USBケーブルによるダウンロードができなかった。USBシリアル変換チップを使い、PCのOSからはシリアル通信としてターゲットの ESP32 DevKitC と通信する。VirtualBox 上の Ubuntu から Win10(64bit) の USBデバイスを使えるように設定できるのだが、なぜかうまく動かなかった。Ubuntuがハングアップしてしまう。

 

そこで。VirtualBox 上の Ubuntu ではなく、素の Ubuntu  なら簡単にうまく行くはず、と思い、USBメモリUbuntu をインストールした。 Ubuntu の Live USB メモリを作成した。

 

USBメモリから Ubuntu を起動。 apt-get update & upgrade 後に、 ESP32 の環境構築をした。無事に最初のサンプル HelloWorld をビルドし、ターゲットの ESPDevKitC に書き込むことができた。 make flash で書き込み、 make monitor でシリアル通信の確認ができた。

 

この際、 /dev/ttyUSB0 の Permission Denied になった。 このデバイスは dialout グループに属しており、rw 可能になっている。自分を dialout グループに登録すればよい。

$ sudo adduser kzono dialout

ただし! いったんログアウトしないと、有効にならない。

 

【ESP32】arduino IDE シリアル通信できた

Arduino のシリアル通信のスケッチがそのまま動いた。(^^)

esp32用ライブラリがシリアル通信をサポートしているということ。

  1. GPIO:LEDとスイッチ
  2. ADC:可変抵抗器(ボリューム)、各種センサ(加速度)
  3. Timer(PWM):LED調光、スピーカ、DCモータ、サーボモータ
  4. SDカードの読み書き
  5. WiFi:文字列、バイナリデータをソケットで。
  6. BluetoothWiFiと同様。

要素技術としてこのくらいできれば、いろんなアプリケーションを作れる。

arduino IDE で試したあと、espressif  esp-idf も試す。

  • esp WROOM-2
  • esp WROOM32
  • mbed(stm32)

をほぼ同じように動かせるはず。RaspberryPi と役割分担を考えたい。上記のレベルであれば RasPiは不要。RapPi でないとできないこと

  • OpenCV による画像認識、画像処理
  • 動画のストリーミング
  • Alexir, watson などを利用

などをさせるべき。Linux であることの利点をいかすべき。

  • メモリをたくさん必要とする処理