UDP でメッセージを送受信

説明の画像

DOS モードで UDP(User datagram protocol) 送信と、UDP 受信を行うプログラムを作成します。
送信\Main.cpp⇒"HELLO"⇒受信\Main.cpp

前田稔(Maeda Minoru)の超初心者のプログラム入門

メッセージの送信/受信

  1. 送信側から UDP で "HELLO" を送信して、受信側で受け取って表示します。
    UDP ではメッセージが無事に相手側に届いたか否かは関知しません。
    受信側の準備ができていないとメッセージは捨てられます。
  2. 送信に先だって、受信側のプログラムを起動して下さい。
    1. 受信側のプログラムの手順です。
      1. ソケットを作る
      2. 接続相手を設定する
      3. 接続(bind)する
      4. データを受け取る
    2. Win32 コンソールアプリケーションを作成して受信側の main.cpp をプロジェクトに追加します。
    3. winsock2.h をインクルードして ws2_32.lib をリンクしなければならないのですが #pragma でリンクするので特に操作は不要です。
    4. プロジェクトをビルドして受信側の Main.exe を実行して下さい。
      2011/9 Windows7 で実行すると「Windows セキュリティの重要な警告」画面が表示されました。
      「アクセスを許可する(A)」をクリックすると、実行が行われます。
      セキュリティは、現在最も重要なテーマであり、頻繁に改良が加えられていて様子が変わるかも知れません。

    5. プログラムが起動するとコマンドプロンプトのウインドウが表示されます。
      そのままの状態で、送信側のプログラムが起動するのを待って下さい。
    6. 受信側の画面に送られてきたメッセージ("HELLO") が表示されるのを確認して下さい。
      何かキーをタイプすると受信側が終了します。
  3. 受信側が起動していることを確認してから送信して下さい。
    1. 送信側のプログラムの手順です。
      1. ソケットを作る
      2. 送信相手を設定する
      3. データを送信する
      4. 送信が終わると終了する
    2. Win32 コンソールアプリケーションを作成して送信側の main.cpp をプロジェクトに追加します。
    3. winsock2.h をインクルードして ws2_32.lib をリンクしなければならないのですが #pragma でリンクするので特に操作は不要です。
    4. プロジェクトをビルドして送信側の Main.exe を実行して下さい。
      送信が終わるとすぐにウインドウが閉じられます。
  4. ファイアウォールを元に戻します。
    1. WindowsXP では [コントロールパネル][ネットワーク接続] を開いて、ローカルエリア接続のプロパティから [詳細設定][詳細] ボタンで [Windows ファイアウォール] を有効に戻して下さい。
    2. Windows7 の場合はそのままでも構いませんが、テストが終われば二度と実行することは無いので、元の状態に戻します。
      「コントロールパネル/Windowsファイアウォール/詳細設定/受信の規則」を表示して下さい。
      ここに受信側のプログラム(私の場合は main.exe)が追加されていました。
      日付やフォルダ名で良く確認してから削除して下さい。
      間違って削除するとシステムに支障をきたす恐れがあります。
      セキュリティは、現在最も重要なテーマであり、頻繁に改良が加えられていて様子が変わるかも知れません。

ソースコード

  1. 送信側の全ソースコード
    /**************************/
    /*★  UDP 送信 Program  ★*/
    /**************************/
    #include    <winsock2.h>
    #pragma     once
    #pragma     comment(lib,"ws2_32.lib")
    
    int main()
    {   WSAData wsaData;
        SOCKET  sock;
        struct  sockaddr_in addr;
    
        WSAStartup(MAKEWORD(2,0), &wsaData);
        sock = socket(AF_INET, SOCK_DGRAM, 0);
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(12345);
        addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    
        sendto(sock, "HELLO", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
    
        closesocket(sock);
        WSACleanup();
    
        return 0;
    }
    
  2. 受信側の全ソースコード
    /**************************/
    /*★  UDP 受信 Program  ★*/
    /**************************/
    #include    <stdio.h>
    #include    <conio.h>
    #include    <winsock2.h>
    #pragma     once
    #pragma     comment(lib,"ws2_32.lib")
    
    int main()
    {   WSAData wsaData;
        SOCKET  sock;
        struct  sockaddr_in addr;
        char    buf[2048];
    
        WSAStartup(MAKEWORD(2,0), &wsaData);
        sock = socket(AF_INET, SOCK_DGRAM, 0);
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(12345);
        addr.sin_addr.S_un.S_addr = INADDR_ANY;
    
        bind(sock, (struct sockaddr *)&addr, sizeof(addr));
    
        memset(buf, 0, sizeof(buf));
        recv(sock, buf, sizeof(buf), 0);
    
        printf("%s\n", buf);
    
        closesocket(sock);
        WSACleanup();
        getch();
    
        return 0;
    }
    

プログラムの説明

  1. 送信側プログラムの説明です。
    1. WSAStartup() 関数で Winsock を初期化して、ソケットを作成します。
      プログラムを解かりやすくするために、エラーの処理を省略しています。
      この辺は受信側も送信側も同じです。
              int main()
              {   WSAData wsaData;
                  SOCKET  sock;
                  struct  sockaddr_in addr;
      
                  WSAStartup(MAKEWORD(2,0), &wsaData);
                  sock = socket(AF_INET, SOCK_DGRAM, 0);
              
    2. 接続先指定用構造体に送信相手を設定して sendto() でメッセージ("HELLO")を送信します。
      "127.0.0.1"(ネットワークに出さずに折り返し) が IP アドレスで、12345 はポート番号です。
                  addr.sin_family = AF_INET;
                  addr.sin_port = htons(12345);
                  addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
      
                  sendto(sock, "HELLO", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
              
    3. 送信が終わると直ちに終了します。
      UDP ではメッセージが無事に相手側に届いたか否かは関知しません。
                  closesocket(sock);
                  WSACleanup();
      
                  return 0;
              }
              
  2. 受信側プログラムの説明です。
    1. WSAStartup() 関数で Winsock を初期化して、ソケットを作成します。
              int main()
              {   WSAData wsaData;
                  SOCKET  sock;
                  struct  sockaddr_in addr;
                  char    buf[2048];
      
                  WSAStartup(MAKEWORD(2,0), &wsaData);
                  sock = socket(AF_INET, SOCK_DGRAM, 0);
              
    2. 接続先指定用構造体を設定して bind() でポートに接続します。
      INADDR_ANY(誰でもいいから) が IP アドレスで、12345 はポート番号です。
                  addr.sin_family = AF_INET;
                  addr.sin_port = htons(12345);
                  addr.sin_addr.S_un.S_addr = INADDR_ANY;
       
                  bind(sock, (struct sockaddr *)&addr, sizeof(addr));
              
    3. recv() でメッセージを受け取り printf() で表示します。
      WindowsXP では、コマンドプロンプトのウインドウがすぐに閉じられるので getch() で表示確認をしています。
                  memset(buf, 0, sizeof(buf));
                  recv(sock, buf, sizeof(buf), 0);
      
                  printf("%s\n", buf);
      
                  closesocket(sock);
                  WSACleanup();
                  getch();
                  return 0;
              }
              

【NOTE】

  1. プログラムを起動したときに表示されるセキュリティの警告画面です。
    XP の最初の頃は [コントロールパネル][ネットワーク接続] を開いて、ローカルエリア接続のプロパティから [詳細設定][詳細] ボタンで [Windows ファイアウォール] を無効にしていました。
    セキュリティは、現在最も重要なテーマであり、頻繁に改良が加えられていて様子が変わるかも知れません。
  2. ファイアウォールの画面です。
    Windows7 では「コントロールパネル/Windowsファイアウォール/詳細設定/受信の規則」で表示されるのですが、OS によって多少違います。

超初心者のプログラム入門(Win32API C++)