前回まで三菱MCプロトコルのライブラリをつくるため通信テストをしてきましたが、プロクラムの中にASIOの記述をずらずらと書いていたのでクラスにまとめてモジュール化しようと考えています。
クラスにするだけでも、結構苦労しました。特にsocketをローカル変数宣言して、コンストラクタで設定するところです。構造体のデータを転送してみましたが、エラーが発生してうまく行かなかったので、まずはnetcatで立ち上げたローカルサーバへの送信プログラムを作ってみました。プログラムはgistへアップしましたので参照してください。
UDPClient
早速説明していきます。UDPClientクラスの変数はendpointとsocketを宣言します。コンストラクタではio_contextとIPアドレスとポート番号を受けて、socketとendpointを初期化しています。
class UDPClient
{
private:
asio::ip::udp::endpoint endpoint;
asio::ip::udp::socket socket;
public:
UDPClient(
asio::io_context& io_contex,
const std::string host,
const short port)
: socket(io_contex)
{
asio::ip::udp::endpoint endpoint_(asio::ip::address::from_string(host), port);
endpoint = endpoint_;
}
UDP送信は構造体で送信することを考えて、テンプレートで作成しました。(まだ実際に構造体での転送は試していません。)
template <typename T>
void Send(T msg,int size)
{
socket.send_to(asio::buffer(&msg, size, endpoint);
}
mainの中は次のとおりです。io_contexとIPアドレスとポート番号を指定してクラスを宣言し、キーボードで入力した文字をUDPサーバへ送信するだけのプログラムです。
asio::io_context io_context;
const std::string host = "127.0.0.1";
const short port = (short)60000;
UDPClient udp(io_context,host,port);
udp.Open();
for(;;)
{
std::string inmsg;
getline(std::cin, inmsg);
if(inmsg=="q") break;
inmsg+="\r\n\r\n";
udp.Send(inmsg,inmsg.size());
}
udp.Close();
私のMacbook環境ではnetcatが使えるのでnetcatが使えるので、netcatをUDPサーバ、ポート番号60000で立ち上げて、文字が表示することを確認しました。
$ netcat -l -u -p 60000
メインのプログラムでinmsg+=”\r\n\r\n”;としているのは、netcatでうまく開業されなかったからです。他に1文字か2文字だと一段多く改行したり、十何文字か多く打つと文字が変になったりするのですが、とりあえずモジュール化して通信できるました。
次は受信についてやり、構造体のデータを送ります。