2016年11月15日火曜日

C++を使ってUDPに接続してみた

UDPにて相互に通信をしたいという要求が多々あるかと思います。前回の記事ではPerl言語を用いたのですが、やはりプログラミング言語の世界における実質的な標準言語であるC++言語で記述したいでしょう。とりあえず、Windows環境でSocketを使って開発する場合です。筆者はVisual Studioにて記述しました。

とりあえず、サーバ側とクライアント側と2つのプログラムを用意します。サーバ側は9000番のUDPにて待ち受けていて、届いた文字列を表示させて終了とします。クライアント側は、サーバ側に対してメッセージを送ってみたいと思います。

サーバ側のメイン処理は次の通りです。


   WSAData wsa;
   if ( 0 != WSAStartup ( MAKEWORD ( 2, 0 ), &wsa ) )
      return ( 1 ); // error;

   SOCKET sock;
   if ( INVALID_SOCKET == ( sock = socket ( AF_INET, SOCK_DGRAM, 0 ) ) )
      return ( 1 );  // error;

   struct sockaddr_in addr;
   addr.sin_family = AF_INET;
   addr.sin_port = htons ( 9000 );
   addr.sin_addr.S_un.S_addr = INADDR_ANY;

   bind ( sock, ( struct sockaddr* ) &addr, sizeof(addr) );
   
   char buffer[2048];
   memset ( buffer, 0, sizeof(buffer) );
   
   recv ( sock, buffer, sizeof(buffer), 0 );
   fprintf ( stdout, "%s\n", buffer );

   closesocket ( sock );
   WSACleanup();


クライアント側のメイン処理は次の通りです。

   WSAData wsa;
   if ( 0 != WSAStartup ( MAKEWORD ( 2, 0 ), &wsa ) )
      return ( 1 ); // error;

   SOCKET sock;
   if ( INVALID_SOCKET == ( sock = socket ( AF_INET, SOCK_DGRAM, 0 ) ) )
      return ( 1 );  // error;

   struct sockaddr_in addr;
   addr.sin_family = AF_INET;
   addr.sin_port = htons ( 9000 );
   addr.sin_addr.S_un.S_addr = inet_addr ( "127.0.0.1" );

   char message[] = "Hello world";
   sendto ( sock, message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr) );

ちなみに、Socketを取り扱うためのヘッダファイルとライブラリをインクルードする必要がありまして、例えば次のように記述してみました。いうまでもなく、クライアント側はstrlen( )関数を使うために、<string.h>をインクルードする必要があります。

#pragma comment(lib,"Ws2_32.lib")
#include <winsock2.h>

さて、パパッとコンパイル&ビルドをして、2つの実行ファイルを作成します。


動作確認として、コマンドプロンプトから、先にudp_serverを実行して、後からudp_clientを実行してみます。所望の動作をしていることが確認できました。


ちなみに、Linuxに移植するときは、ヘッダファイルやライブラリの変更が必要で、いくつかのおまじないの流儀が違いますので...。