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