Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualRasterman

Posted 21 December 2012 - 05:21 PM

Here are the broadcast util functions I made for my game, you should be able to add full LAN discovery with only a few additional lines of code.

	// http://lists.cubik.org/pipermail/enet-discuss/2009-March/001075.html
	
	// designed for LAN discovery of servers
	// sets up a socket to receive broadcast messages on the given port
	int enetutil_broadcast_setup_receive(int port)
	{
		ENetAddress address;
		address.host = ENET_HOST_ANY;
		address.port = m_iLANDiscoveryPort;

		// create UDP socket
		ENetSocket socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
		if(socket == ENET_SOCKET_NULL)
			return ENET_SOCKET_NULL;

		// allow multiple servers on the same computer to listen to same port
		enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1);

		// bind to the address to listen on after REUSEADDR has been set
		if(enet_socket_bind(socket, &address) < 0)
		{
			enet_socket_destroy(socket);
			return ENET_SOCKET_NULL;
		}

		// no blocking again
		enet_socket_set_option(socket, ENET_SOCKOPT_NONBLOCK, 1);

		return socket;
	}


	// designed for LAN discovery of servers
	// broadcasts the given data on the port specified
	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_broadcast_send(int port, void *data, int length)
	{
		ENetAddress address;
		address.host = ENET_HOST_BROADCAST;
		address.port = port;

		return enetutil_send(&address, data, length);
	}


	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_send(ENetAddress *address, void *data, int length)
	{
		// create UDP socket
		ENetSocket socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
		if(socket == ENET_SOCKET_NULL)
			return -1;

		// prevent send from blocking
		enet_socket_set_option(socket, ENET_SOCKOPT_NONBLOCK, 1);
		// allow the socket to send to the broadcast address
		if(address->host == ENET_HOST_BROADCAST)
			enet_socket_set_option(socket, ENET_SOCKOPT_BROADCAST, 1);

		ENetBuffer buf;
		buf.data = data;
		buf.dataLength = length;
		int err = enet_socket_send(socket, address, &buf, 1);
		if(err==0) { /* would have blocked, need to resend later */ return 0; }
		else if(err < 0) { /* something went wrong, error! */ return err; }

		enet_socket_destroy(socket);
		return length;
	}

#2Rasterman

Posted 21 December 2012 - 05:20 PM

Here are the broadcast util functions I made for my game, you should be able to add full LAN discovery with only a few additional lines of code.

	// http://lists.cubik.org/pipermail/enet-discuss/2009-March/001075.html
	
	// designed for LAN discovery of servers
	// sets up a socket to receive broadcast messages on the given port
	int enetutil_broadcast_setup_receive(int port)
	{
		ENetAddress address;
		address.host = ENET_HOST_ANY;
		address.port = m_iLANDiscoveryPort;

		// create UDP socket
		ENetSocket socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
		if(socket == ENET_SOCKET_NULL)
			return ENET_SOCKET_NULL;

		// allow multiple servers on the same computer to listen to same port
		enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1);

		// bind to the address to listen on after REUSEADDR has been set
		if(enet_socket_bind(socket, &address) < 0)
		{
			enet_socket_destroy(socket);
			return ENET_SOCKET_NULL;
		}

		// no blocking again
		enet_socket_set_option(socket, ENET_SOCKOPT_NONBLOCK, 1);

		return socket;
	}


	// designed for LAN discovery of servers
	// broadcasts the given data on the port specified
	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_broadcast_send(int port, void *data, int length)
	{
		ENetAddress address;
		address.host = ENET_HOST_BROADCAST;
		address.port = port;

		return enetutil_send(&address, data, length);
	}


	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_send(ENetAddress *address, void *data, int length)
	{
		// create UDP socket
		ENetSocket socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
		if(socket == ENET_SOCKET_NULL)
			return -1;

		// prevent send from blocking
		enet_socket_set_option(socket, ENET_SOCKOPT_NONBLOCK, 1);
		// allow the socket to send to the broadcast address
		if(address->host == ENET_HOST_BROADCAST)
			enet_socket_set_option(socket, ENET_SOCKOPT_BROADCAST, 1);

		ENetBuffer buf;
		buf.data = data;
		buf.dataLength = length;
		int err = enet_socket_send(socket, address, &buf, 1);
		if(err==0) { /* would have blocked, need to resend later */ return 0; }
		else if(err < 0) { /* something went wrong, error! */ return err; }

		enet_socket_destroy(socket);
		return length;
	}


	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_send(ENetHost *host, ENetAddress *address, void *data, int length, int ttl = 0)
	{
		if(!host)
			return -1;

		ENetSocket socket = host->socket;
		if(socket == ENET_SOCKET_NULL)
			return -1;

		int result, origttl = 0;

		if(ttl != 0)
		{
			// if getsockopt returns SOCKET_ERROR setting TTL is not supported
			socklen_t len=sizeof(int);
			result = getsockopt(socket, IPPROTO_IP, IP_TTL, (char *) & origttl, &len);
			if(result == SOCKET_ERROR)
				return -2;

			// set ttl to custom value
			result = setsockopt(socket, IPPROTO_IP, IP_TTL, (char *) & ttl, sizeof (int));
			if(result == SOCKET_ERROR)
				return -2;
		}

		ENetBuffer buf;
		buf.data = data;
		buf.dataLength = length;
		int err = enet_socket_send(socket, address, &buf, 1);
		if(err==0) { /* would have blocked, need to resend later */ return 0; }
		else if(err < 0) { /* something went wrong, error! */ return err; }

		if(ttl != 0)
		{
			// restore ttl on socket
			result = setsockopt(socket, IPPROTO_IP, IP_TTL, (char *) & origttl, sizeof (int));
			if(result == SOCKET_ERROR)
				return -2;
		}

		return length;
	}

#1Rasterman

Posted 21 December 2012 - 05:17 PM

Here are the broadcast util functions I made for my game

	// http://lists.cubik.org/pipermail/enet-discuss/2009-March/001075.html
	
	// designed for LAN discovery of servers
	// sets up a socket to receive broadcast messages on the given port
	int enetutil_broadcast_setup_receive(int port)
	{
		ENetAddress address;
		address.host = ENET_HOST_ANY;
		address.port = m_iLANDiscoveryPort;

		// create UDP socket
		ENetSocket socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
		if(socket == ENET_SOCKET_NULL)
			return ENET_SOCKET_NULL;

		// allow multiple servers on the same computer to listen to same port
		enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1);

		// bind to the address to listen on after REUSEADDR has been set
		if(enet_socket_bind(socket, &address) < 0)
		{
			enet_socket_destroy(socket);
			return ENET_SOCKET_NULL;
		}

		// no blocking again
		enet_socket_set_option(socket, ENET_SOCKOPT_NONBLOCK, 1);

		return socket;
	}


	// designed for LAN discovery of servers
	// broadcasts the given data on the port specified
	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_broadcast_send(int port, void *data, int length)
	{
		ENetAddress address;
		address.host = ENET_HOST_BROADCAST;
		address.port = port;

		return enetutil_send(&address, data, length);
	}


	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_send(ENetAddress *address, void *data, int length)
	{
		// create UDP socket
		ENetSocket socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
		if(socket == ENET_SOCKET_NULL)
			return -1;

		// prevent send from blocking
		enet_socket_set_option(socket, ENET_SOCKOPT_NONBLOCK, 1);
		// allow the socket to send to the broadcast address
		if(address->host == ENET_HOST_BROADCAST)
			enet_socket_set_option(socket, ENET_SOCKOPT_BROADCAST, 1);

		ENetBuffer buf;
		buf.data = data;
		buf.dataLength = length;
		int err = enet_socket_send(socket, address, &buf, 1);
		if(err==0) { /* would have blocked, need to resend later */ return 0; }
		else if(err < 0) { /* something went wrong, error! */ return err; }

		enet_socket_destroy(socket);
		return length;
	}


	// returns:  0 if would have blocked, -1 if socket could not be created, < 0 something went wrong, length on success
	int enetutil_send(ENetHost *host, ENetAddress *address, void *data, int length, int ttl = 0)
	{
		if(!host)
			return -1;

		ENetSocket socket = host->socket;
		if(socket == ENET_SOCKET_NULL)
			return -1;

		int result, origttl = 0;

		if(ttl != 0)
		{
			// if getsockopt returns SOCKET_ERROR setting TTL is not supported
			socklen_t len=sizeof(int);
			result = getsockopt(socket, IPPROTO_IP, IP_TTL, (char *) & origttl, &len);
			if(result == SOCKET_ERROR)
				return -2;

			// set ttl to custom value
			result = setsockopt(socket, IPPROTO_IP, IP_TTL, (char *) & ttl, sizeof (int));
			if(result == SOCKET_ERROR)
				return -2;
		}

		ENetBuffer buf;
		buf.data = data;
		buf.dataLength = length;
		int err = enet_socket_send(socket, address, &buf, 1);
		if(err==0) { /* would have blocked, need to resend later */ return 0; }
		else if(err < 0) { /* something went wrong, error! */ return err; }

		if(ttl != 0)
		{
			// restore ttl on socket
			result = setsockopt(socket, IPPROTO_IP, IP_TTL, (char *) & origttl, sizeof (int));
			if(result == SOCKET_ERROR)
				return -2;
		}

		return length;
	}

PARTNERS