Jump to content
  • Advertisement
Sign in to follow this  
MatiasMunk

[Enet] Multiple Client connections

This topic is 560 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm developing a client/server for a simple game I'm making, but I have no clue on how to handle several clients?

I've read a few threads here and there with the same issue, but no "solve" was posted when solved.

Here we have the server

#include <iostream>
#include <enet/enet.h>

int main(int argc, char** argv) {

	ENetAddress address;
	ENetHost* server;

	if (enet_initialize() != 0) {
		fprintf(stderr, "Failed to initialize ENet!\n");
		exit(-1);
	}

	// Bind the server to default localhost
	// Specified host address can be specified by
	// enet_address_set_host(&address, "x.x.x.x");

	address.host = ENET_HOST_ANY;

	// Bind the server to port 1234
	address.port = 8484;

	server = enet_host_create(&address /* the address to bind the server host to */,
		32      /* allow up to 32 clients and/or outgoing connections */,
		2      /* allow up to 2 channels to be used, 0 and 1 */,
		0      /* assume any amount of incoming bandwidth */,
		0      /* assume any amount of outgoing bandwidth */);
	if (server == NULL)
	{
		fprintf(stderr,
			"An error occurred while trying to create an ENet server host.\n");
		exit(EXIT_FAILURE);
	}
	else {
		std::cout << "MSC++Server has started" << std::endl << "Listening on IP: " << address.host << " Port: " << address.port << "." << std::endl;
	}

	ENetEvent event;

	while (true) {
		/* Wait up to 1000 milliseconds for an event. */
		while (enet_host_service(server, &event, 1000) > 0)
		{
			switch (event.type)
			{
			case ENET_EVENT_TYPE_CONNECT:
				printf("New connection from %x:%u.\n",
					event.peer->address.host,
					event.peer->address.port);
				/* Store any relevant client information here. */
				event.peer->data = "Client";
				break;
			case ENET_EVENT_TYPE_RECEIVE:
				printf("A packet of length %u containing %s was received from %s on channel %u.\n",
					(unsigned int)event.packet->dataLength,
					event.packet->data,
					event.peer->data,
					event.channelID);
				/* Clean up the packet now that we're done using it. */
				enet_packet_destroy(event.packet);
				break;

			case ENET_EVENT_TYPE_DISCONNECT:
				printf("%s disconnected.\n", event.peer->data);
				/* Reset the peer's client information. */
				event.peer->data = NULL;
			}
		}
	}

	atexit(enet_deinitialize);
}

This particular code especially

case ENET_EVENT_TYPE_CONNECT:
	printf("New connection from %x:%u.\n",
	event.peer->address.host,
	event.peer->address.port);
	/* Store any relevant client information here. */
	event.peer->data = "Client";
break;

I have a "peer" or client if you will, with some data.
This connection is a single connection that can be established to the server, meaning if I instance a new client, the first client will have it's data overwritten.

How do I overcome this issue?

Share this post


Link to post
Share on other sites
Advertisement

I don't know ENet, but looking over the docs and your code quickly, I don't see an immediate problem, but I'm lacking some context.

You _should_ be receiving a single CONNECT message per client connection, and each one should have a unique instance of ENetPeer which you can freely modify and store data upon as in your code. You should not be receiving a DISCONNECT message between the first and second client connection if you're expecting them both to be active; are you? Are the addresses of your peer pointers difference for each CONNECT message or is the same peer being recycled?

Highly unrelated note:

    // Bind the server to port 1234
    address.port = 8484;

this is a perfect example of why comments should not just repeat what the code is (supposedly) doing. :)

Share this post


Link to post
Share on other sites

It's been about 8 years since I last used Enet, but it creates one 'peer' for every remote client that connects. I vaguely recall that you will need to remember each peer that is presented to you in this way, perhaps by copying the pointer to the peer and storing it in your program, and removing it if you get the disconnect message.

Share this post


Link to post
Share on other sites

This connection is a single connection that can be established to the server, meaning if I instance a new client, the first client will have it's data overwritten.


event.peer->data = "Client";



Here is where you're supposed to allocate your own client management structure and assign it to the peer data field.
Each time Enet gets data from a particular peer, you can figure out which peer you think it is by looking at this "data" field of the peer passed into the various events.

Share this post


Link to post
Share on other sites

Just so I'm not misunderstanding;

So I should put create the "peer" as an array and save client information into an empty index, then consistently check up on events and add updates to the client information as they do events in the game (Which I of course will be handling server side to prevent any client hacks). Am I right or nah? ^^

Edited by MatiasMunk

Share this post


Link to post
Share on other sites

You don't create the peers - ENet does. Each one represents a remote connection. So you need to associate those peers with whatever other data you need to store about a remote connection. You can make the peer's 'data' pointer refer to your local player data, so that when you get an event, you can find out which player it is by looking at peer->data. You probably want a reference in the other direction as well, so that you can easily find the correct peer for each player when you want to send data via enet_peer_send.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!