Socket通信を始めるとき、まず初めに試してみるとよいのがUDP方式による通信。 接続を確保して欠落なくデータを送るTPCと 一方的にデータを送りつけるだけのUDPを比べると、 UDPの方が単純なのでプログラムも分かりやすい。 C++ライブラリであるBoostを使えば簡単に実現できるが、Boost本家のサンプルコードはいまいち分かりにくかったので、 導入用のサンプロコードをここにメモしておく。
サンプルコード(Visual Studio2010):
https://github.com/r168xr169/BoostUdpSocket
送信側
送信側がやることは、ソケットをオープンしたら、ただただデータを送りつけるだけ。 データを送りつける先のIPアドレス(192.168.0.100など)、ポート番号とプロトコル(IPv4/IPv6)を指定する必要がある。 ここでは送信データとして「BoostSocketUDP 001\n」などの番号入りのテキストを送ることにする。 for文を無限ループにしているので、このテキスト内の番号がインクリメントされる仕組みである。 また、送信先のIPv4アドレスは192.168.0.100、ポート番号は1234とした。
#include <string> #include <iostream> #include <boost/asio.hpp> #include <boost/format.hpp> #include <boost/thread.hpp> int main(int argc, char * argv[]) { using namespace boost::asio::ip; //ソケットオープン boost::asio::io_service io_service; udp::socket sock(io_service, udp::endpoint(udp::v4(), 1234)); //繰り返し送信する for(int i=0; true; i++) { //テキストの送信(相手の状態に関わらず送信し終えたらすぐに次の処理に移る) std::string str = (boost::format("BoostSocketUDP %03d\n") % i).str(); sock.send_to ( boost::asio::buffer(str), udp::endpoint(address::from_string("192.168.0.100"), 1234) ); //1秒待機(送信しすぎないように) std::cout << str; boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } return 0; }
受信側
受信側でもやはりソケットをオープンした後、ポートとプロトコルを指定すれば、 あとはreceive_from()関数で受信すれば良い。 こちらもIPv4、ポート番号1234とした。
#include <string> #include <iostream> #include <boost/asio.hpp> #include <boost/array.hpp> int main(int argc, char * argv[]) { using namespace boost::asio::ip; //ソケットオープン boost::asio::io_service io_service; udp::socket sock(io_service, udp::endpoint(udp::v4(), 1234)); //繰り返しテキストを受信する for(int i=0; true; i++) { //受信(受信できるまで待機される) boost::array<char, 128> recv_buf; udp::endpoint endpoint; size_t len = sock.receive_from(boost::asio::buffer(recv_buf), endpoint); //受信内容を表示 std::cout.write(recv_buf.data(), len); } return 0; }
上手くいかないとき・・・
- OSやウィルスソフトのファイヤーウォールでブロックされていないか確認する。二重にブロックされていることもある。
- 同じプライベートIPアドレス(192.168.*.*)に見えても異なる無線LANのアクセスポイントに接続されている場合は、セグメントが異なるのでプライベートIPアドレスどうしでは通信できない。
- 同じPC上で上記の2つのプログラムを動作させることはできない。
- WindowsならMicrosoft Network Monitorで通信内容をキャプチャできるので、デバッグに使える。
参考
- Boost 1.35.0 Tutorial
http://www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/tutorial.html - Microsoft Network Monitor
http://www.microsoft.com/en-us/download/details.aspx?id=4865