my code stock.com

jesseconnell

Create Boost.Asio multicast receive socket
by jesseconnell

Snippet options

Download: Download snippet as create-boostasio-multicast-receive-socket.c.
Copy snippet: For this you need a free my code stock.com account.
Embed code : You will find the embed code for this snippet at the end of the page, if you want to embed it into a website or a blog!

// TestMCast.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
//#include <winsock2.h>
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <windows.h>
#include <sstream>

using namespace std;

boost::system::error_code OpenMCastSocket(
	boost::asio::ip::udp::socket& sock,
	const string& ipAddress,
	const string& localAddress,
	unsigned short port,
	bool blocking = true
	)
{
	using namespace boost::asio::ip;

	boost::system::error_code ec;

	address_v4 locAddr = address_v4::from_string(localAddress, ec);
	address_v4 mcAddr = address_v4::from_string(ipAddress, ec);
	udp::endpoint mcastEndpoint = udp::endpoint(locAddr, port);

	stringstream ss;
	ss << "OpenMCastSocket(socket&, ipAddress=" << ipAddress << ", localAddress=" << localAddress << ", port=" << port << ", blocking=" << blocking << ")";
	string functionCall = ss.str();

	if (sock.open(mcastEndpoint.protocol(), ec))
	{
		cout << functionCall << " failed to open socket.  Error=" << ec.message() << endl;
	}
	else
	{
		std::string task;

		for (;;)
		{
			task = "set_option(reuse_address)";
			if (sock.set_option(udp::socket::reuse_address(true), ec)) break;
			
			// sock is now open. Any failure in this scope will require a close() 
			task = "set_option(enable_loopback)";
			if (sock.set_option(multicast::enable_loopback(false), ec)) break;

			task = "bind(endpoint: (localAddress,port))";
			if (sock.bind(mcastEndpoint, ec)) break;

			task = "join_group(ipAddress,localAddress)";
			if (sock.set_option(boost::asio::ip::multicast::join_group(mcAddr, locAddr), ec)) break;
			
			if (blocking)
			{
				boost::asio::socket_base::non_blocking_io command(true);
				task = "set_option(non_blocking_io)";
				if (sock.io_control(command, ec)) break;
			}
			break;
		}

		if (ec)
		{
			cout << functionCall << " failed during task: " << task 
				<< ".  Socket FD = " << sock.native() 
				<< ".  Error=" << ec.message() << endl;

			if (sock.close(ec))
			{
				cout << "also failed trying to close the socket.  Error=" << ec.message() << endl;
			}
		}
	}
	return ec;
}

int _tmain(int argc, _TCHAR* argv[])
{
	boost::asio::io_service ioservice;
	boost::asio::ip::udp::socket s(ioservice);

	boost::system::error_code ec = OpenMCastSocket(s, "239.1.2.3", "0.0.0.0", 5555, false);
	if (ec)
	{
		cout << ec.message() << endl;
		return 0;
	}
	char data[100000];
	bool running = true;
	int lastres = 0;
	while (running)
	{
		cout << '.';
		WSASetLastError(0);
		int res = recv(s.native(), data, 10000, 0);
		if (res > 0)
		{
			cout << "\nReceived " << res << " bytes\n";
			if (res - lastres != 1)
			{
 				cout << "WTF!!!!!!!!" << endl;
			}
			lastres = res;
		}
		else
		{
			if (res == -1)
			{
				if (WSAGetLastError() != WSAEWOULDBLOCK)
				{
					cout << WSAGetLastError() << endl;
				}
			}
		}
		running = data[0] != 'Q';
	}

	return 0;
}

Create a free my code stock.com account now.

my code stok.com is a free service, which allows you to save and manage code snippes of any kind and programming language. We provide many advantages for your daily work with code-snippets, also for your teamwork. Give it a try!

Find out more and register now

You can customize the height of iFrame-Codes as needed! You can find more infos in our API Reference for iframe Embeds.