LoginSignup
3
3

More than 5 years have passed since last update.

Windows Console でUDPのマルチキャスト受信

Last updated at Posted at 2016-01-30

minGW を使った、UDPのマルチキャスト受信関数

windows 7 のDOS窓で動作する関数です。

udprcvmc.c
#include <stdio.h>
#include <fcntl.h>
#include <winsock.h>
#include <string.h>

int main()
{
    int sock, err;
    struct sockaddr_in addr;
    struct ip_mreq mreq;
    WSADATA wsaData;
    char buf[2048];

    // winsock2の初期化
    WSAStartup(MAKEWORD(2,0), &wsaData);

    //socketシステムコール
    //ディスクリプタsdを取得する
    //SOCK_DGRAM <- UDP, SOCK_STREAM<- TCP
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket");
        printf("error:%d\n",WSAGetLastError());
        return 1;
    }

    // 受信元アドレスとポート番号を設定する
    addr.sin_family = AF_INET;
    addr.sin_port = htons(12345);       //IPアドレスを格納したin_addr構造体
    addr.sin_addr.s_addr = INADDR_ANY;  // ポート番号(htons)でネットワークバイトオーダーに変換

    // ソケットに名前(ポート番号 & IPアドレス)を付ける
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind");
        printf("error:%d\n",WSAGetLastError());
        closesocket(sock);
        return -1;
    }

    char loopch=0;

    // IP_MULTICAST_LOOP<- 発信マルチキャスト・データグラムのコピーがマルチキャスト・グループ
    // のメンバーであるかぎり送信しているホストに送達されるようにするかどうかを指定します。
    if ((err=setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
        (char *)&loopch, sizeof(loopch))) < 0) {
        perror("setsockopt");
        printf("error:%d\n",WSAGetLastError());
        closesocket(sock);
        return 1;
        }

    // setsockoptは、bind以降で行う必要あり
    // 受信元アドレスとポート番号を設定する
    memset(&mreq, 0, sizeof(mreq));
    mreq.imr_interface.s_addr = INADDR_ANY;
    mreq.imr_multiaddr.s_addr = inet_addr("127.0.0.1");
    if (setsockopt(sock,
        IPPROTO_IP,
        IP_ADD_MEMBERSHIP,  //受信
        (char *)&mreq, sizeof(mreq)) != 0) {
            perror("setsockopt");
            printf("error:%d\n",WSAGetLastError());
            return 1;
    }

    int recv_len;
    struct sockaddr_in from;
    int sockaddr_in_size = sizeof(struct sockaddr_in);

    while(1){
        memset(buf, 0, sizeof(buf));
        recv_len = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&from, &sockaddr_in_size);
        printf("recv: '%s'(%d) from %s:%d\n", buf, recv_len, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
    }

    // 接続を切断する
    closesocket(sock);
    WSACleanup();
    return 0;
}


コンパイル

gcc udprcvmc.c libwsock32.a

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3