Novell Home

BSD multicast sample

From Developer Community

Shows how to do Multicast with the BSD apis (written in CLIB but should be able to compile with LIBC w/minimal changes).

Sample Code

#include<stdio.h>
#include<sys/types.h>
#include<nlm/sys/socket.h>
#include<nlm/sys/bsdskt.h>
#include<errno.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#define MCAST_ADDRESS "224.0.0.1"
#define SERVER_ADDR "192.168.228.10"
int NLM_Exiting = FALSE;
int NLM_Threads;
int NLM_ServerSocket;

void sigHnd(void)
{
	NLM_Exiting = TRUE;

}

void main(void)
{
    int clientSocket;
	int sizeofClientAddr;
	int iPort = 997;
	char buff[300];
	struct sockaddr_in serverAddr, clientAddr, remoteAddr;
	struct ip_mreq mcastReq;
	int iAddrReuse = TRUE, iTTLValue = 8, iLoop = FALSE;

	NLM_Threads = 1;

	memset((char *)&serverAddr, '\0', sizeof(struct sockaddr_in));
	memset((char *)&clientAddr, '\0', sizeof(struct sockaddr_in));
	memset((char *)&remoteAddr, '\0', sizeof(struct sockaddr_in));
	memset((char *)&mcastReq, '\0', sizeof(struct ip_mreq));
	memset(buff, '\0', sizeof(buff));

	errno = 0;
	if(( NLM_ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == (-1)){
		perror("socket");
		goto END_ERR;
	}

	printf("Setting SOL_SOCET/SO_REUSEADDR\r\n");

	if(setsockopt(NLM_ServerSocket, SOL_SOCKET, SO_REUSEADDR,
					(char *)&iAddrReuse, sizeof(iAddrReuse)) == (-1)){
		perror("setsockopt SO_REUSEADDR");
		goto END_ERR;
	}

	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(iPort);
	serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

	printf("binding to port: %d\r\n", iPort);

	if(( bind(NLM_ServerSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr))) == (-1)){
		perror("bind");
		goto END_ERR;
	}

	remoteAddr.sin_family = AF_INET;
	remoteAddr.sin_port = htons(iPort);
	remoteAddr.sin_addr.s_addr = inet_addr(MCAST_ADDRESS);

	mcastReq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDRESS);
	mcastReq.imr_interface.s_addr = inet_addr(SERVER_ADDR);

	printf("Setting IPPROTO_IP/IP_ADD_MEMBERSHIP\r\n");

	if(setsockopt(NLM_ServerSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,/* 12, 5 */ 
			(char *)&mcastReq, sizeof(mcastReq)) == (-1)){
		perror("setsockopt IP_ADD_MEMBERSHIP");
		printf("errorno = %d", errno);
		goto END_ERR;
	}

	printf("turning off multicast loopback with IPPROTO_IP/IP_MULTICAST_LOOP\r\n");
	if(setsockopt(NLM_ServerSocket, IPPROTO_IP, IP_MULTICAST_LOOP, 
			(char *)&iLoop, sizeof(iLoop)) == (-1)){
		perror("setsockopt IP_MULTICAST_LOOP");
		goto END_ERR;
	}

	printf("Setting TTL value to %d with IPPROTO_IP/IP_MULTICAST_TTL\r\n", iTTLValue);

	if(setsockopt(NLM_ServerSocket, IPPROTO_IP, IP_MULTICAST_TTL,
			(char *)&iTTLValue, sizeof(iTTLValue)) == (-1)){
		perror("setsockopt IP_MULTICAST_TTL");
		goto END_ERR;
	}


	while(!NLM_Exiting)
	{
		sizeofClientAddr = sizeof(clientAddr);
		if(( clientSocket = accept(NLM_ServerSocket, (struct sockaddr *)&clientAddr, &sizeofClientAddr)) == (-1)){
			perror("accept");
			goto END_ERR;
		}

		if(( recv(clientSocket, buff, sizeof(buff), 0)) == (-1)){
			perror("recv");
			goto END_ERR;
		}

		printf("recv: %s\r\n", buff);


		if(( send(clientSocket, buff, strlen(buff), 0)) == (-1)){
			perror("send");
			goto END_ERR;
		}
				
		close(clientSocket);
	}


	printf("All turned out o.k.\r\n");

END_ERR:
	//close(clientSocket);
	close(NLM_ServerSocket);
}

--Benjamin Fjeldsted

Novell® Making IT Work As One

© 2008 Novell, Inc. All Rights Reserved.