[TCP/IP] マルチキャスト

マルチキャストはUDPユニキャストと似ているが、アドレスにメッセージ受信者の集合を指定する。
MutlicastSender.c

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void DieWithError(char *errorMessage);

int main(int argc, char *argv[]){
    int sock;
    struct sockaddr_in multicastAddr;
    char *multicastIP;
    unsigned short multicastPort;
    char *sendString;
    unsigned char mutlicastTTL;
    unsigned int send StringLen;

    if((argc < 4) || (argc > 5)){
        fprintf(stderr, "Usage: %s <Multicast Address><Port><Send String>[<TTL>]\n", argv[0]);
        exit(1);
    }

    multicastIP = argv[1];
    multicastPort = atoi(argv[2]);
    sendString = argv[3];

    if(argc == 5)
        multicastTTL = atoi(argv[4]);
    else
        multicastTTL = 1;

    if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
        DieWithError("socket() failed");

    if(setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *) &multicastTTL, sizeof(multicastTTL)) < 0)
        DieWithError("setsockopt() failed");

    memset(&broadcastAddr, 0, sizeof(broadcastAddr));
    broadcastAddr.sin_family = AF_INET;
    broadcastAddr.sin_addr.s_addr = inet_addr(multicastIP);
    broadcastAddr.sin_port = htons(broadcastPort);

    sendStringLen = strlen(sendString);
    for(;;){
        if (sendto(sock, sendString, sendStringLen, 0, (struct sockaddr *) &multicastAddr, sizeof(multicastAddr), sizeof(multicastAddr)) != sendStringLen)
            DieWithError("sendto() send a different number of bytes than expected.");
        sleep(3);
    }
}
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAXRECVSTRING 255

void DieWithError(char *errorMessage);

int main(int argc, char *argv[]){
    int sock;
    struct sockaddr_in multicastAddr;
    char *multicastIP;
    unsigned short multicastPort;
    char recvString[MAXRECVSTRING+1];
    int recvStringLen;
    struct ip_mreq multicastRequest;

    if(argc != 3){
        fprintf(stderr, "Usage: %s <Multicast IP><Port>]\n", argv[0]);
        exit(1);
    }

    multicastIP = argv[1];
    multicastPort = atoi(argv[2]);

    if((sock = socket(AF_INET, SOCK_GRAM, IPPROTO_UDP)) < 0)
        DieWithError("socket() failed");

    memset(&broadcastAddr, 0, sizeof(broadcastAddr));
    broadcastAddr.sin_family = AF_INET;
    broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    broadcastAddr.sin_port = htons(multicastPort);

    if(bind(sock, (struct sockaddr *) &multicastAddr, sizeof(multicastAddr)) < 0)
        DieWithError("bind() failed");

    muticastRequest.imr_multiaddr.s_addr = inet_addr(multicastIP);
    multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);

    if(setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &multicastRequest, sizeof(multicastRequest))< 0)
        DieWithError("setsockopt() failed");

    if((recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0)) < 0)
        DieWithError("recvfrom() failed");

    recvString[recvStringLen] = 
    printf("Recieved: %s\n", recvString);

    close(sock);
    exit(0);

}

ブロードキャストとマルチキャストのどちらを使用するかは受信を要求するホストの割合や通信相手に関する情報の有無などいくつかの条件を決める必要がある