How to find a host running the game?

Started by
5 comments, last by Rasterman 11 years, 3 months ago
So I have a game that allows you to host or connect to someone hosting a game. I'm using the "enet" network library. The connect fuction for the client requires an IP address to connect too.

I want the client to browse the local network and find any users that have hosted the game and accepting join requests. I don't need any complicated matchmaking service or anything. I just want local network users able to sit down and one person hits host, the other hits join.

Is there some lower level network api calls that would help me accomplish this goal? Right now, I have a text box and the joining user has to enter the IP address of the host.
Advertisement
I'm not familiar with enet but you can use the broadcast address on a LAN to send a packet to all computers on your network with either UDP or IPX.
The FAQ talks a bit about this.

On a LAN, UDP broadcasts can work.

On the Internet, you need some kind of matchmaker, and perhaps also NAT punch-through introducer if you don't want to require your users to set up port forwarding.
enum Bool { True, False, FileNotFound };
If in LAN, use UDP Multicast, it's like broadcast, but it's only shared between a group of devices instead of the whole subnet.

http://en.wikipedia.org/wiki/Multicast

I don't know 'enet' library, but if it's capable of doing UDP, it should do multicast if you bind the socket to a multicast address, but not sure about that.
Thanks for the answers guys. I'll read up on your links. I'm not planning on finding the game on the internet, so I only need to check local networks. So from what you guys are saying.

Client broadcasts a packet on the network.
Server sees this and replies with it's IP address.

i'm a network novice, but usually when setting up a socket the client needs to know a server that is the host. So does this mean that the client spins up a host socket? sends the packet, waits for a response, then closes the socket, and spins up a Client socket using the retrieved IP address information?
To use multicast or broadcast communication, the client must bind to special addresses (see http://en.wikipedia.org/wiki/Multicast_address and http://en.wikipedia.org/wiki/Broadcast_address). Everything sent thru this socket arrives at every device which is binded to the multicast address

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;
	}

This topic is closed to new replies.

Advertisement