I'm trying to develop a simple card game using Allegro and ENET for the multiplayer part. Now, I've found some tutorial online and I came up with a simple code that I'm planning to use for managing the clients/server info exchange during the game. Basically, clients send information about their cards to the server and the server send it back to all clients in order to allow them to update.
When I run the code, the server listen correctly on a port I choose, when I run some clients they successfully connect to the server and start sending messages in loop. The problem is that the first time, the message is sent correctly, afterwards the string is altered. Not only that, after some time both clients disconnect.
Here is my code:
Server Side:
#include <string>
#include <iostream>
#include <enet/enet.h>
#include <string.h>
using namespace std;
//SImple function to send a single packet to all clients
void BroadcastPacket(ENetHost* server, const char* data)
{
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(server, 0, packet);
}
int main()
{
//--Initialize
if(enet_initialize()) { std::cout << ">Couldn't initialize ENET" << std::endl; exit(-1);}
//--Set address to "any"
ENetAddress address;
address.host = ENET_HOST_ANY;
//--Set the port
std::cout << "Port: ";
std::cin >> address.port;
std::cin.clear();
//--Create a server to the address chosen
ENetHost* server;
server = enet_host_create(&address, 6, 2, 0, 0);
if(server == NULL) { std::cout << ">Couldn't initialize host" << std::endl; enet_deinitialize(); exit(1); }
std::string aux;
const char* aux_data;
ENetEvent event;
while(enet_host_service(server, &event, 0) >= 0) {
if(event.type == ENET_EVENT_TYPE_CONNECT) { // client connected
static unsigned int num = 0;
ENetAddress remote = event.peer->address; // peer address
char ip[256];
enet_address_get_host_ip(&remote, ip, 256);
std::cout << "ip:" << ip << " connected, id: " << num << std::endl;
event.peer->data = (void*)num++;
} else if(event.type == ENET_EVENT_TYPE_RECEIVE) { // recv data
std::cout << "received data from: " << event.peer->incomingPeerID << " and data is: > " << (const char*)event.packet->data << std::endl;
//--Add to the packet to send the client ID (just a test in order to
//--modify and resend a packet
const char* data = (const char*)event.packet->data;
std::string str_data{data};
aux.clear();
aux = "<" + to_string(event.peer->incomingPeerID) + ">" + data;
BroadcastPacket(server, aux.c_str());
enet_packet_destroy(event.packet); // free
std::cout << std::endl;
} else if(event.type == ENET_EVENT_TYPE_DISCONNECT) { // disconnect
std::cout << "> Client id" << event.peer->data << " disconnected" << std::endl;
}
}
enet_deinitialize();
return 0;
}
Client Side:
#include <string>
#include <iostream>
#include <enet/enet.h>
using namespace std;
int main()
{
//--Initialize ENET
if(enet_initialize()) { std::cout << ">Couldn't initialize ENET" << std::endl; exit(-1); }
//--Initialize client
ENetHost* client = enet_host_create(NULL, 1, 2, 0, 0);
if(client == NULL) { std::cout << ">Couldn't create client" << std::endl; exit(-1); }
std::string name;
std::cout << "Inser nickname: ";
std::getline(std::cin, name);
//--Initialize address (TODO: extend address for general IP)
ENetAddress address;
if(enet_address_set_host(&address, "127.0.0.1") < 0) { std::cout << ">Host address doesn't exist" << endl; exit(-1); }
//--Choose a port (MATCH IT WITH THE SERVER)
std::cout << "Inser Port number: ";
std::cin >> address.port;
std::cin.clear();
//--Connect with host
ENetPeer* server = enet_host_connect(client, &address, 2, 0);
if(server == NULL) {
std::cout << ">Couldn't connect with host" << std::endl;
exit(-1);
}
//--Define event for polling
ENetEvent event;
if(enet_host_service (client, &event, 5000) > 0 &&
event.type == ENET_EVENT_TYPE_CONNECT) {
std::cout << ">Connected successfully" << std::endl;
} else {
enet_peer_reset (server);
std::cout << "failed to connect" << std::endl;
exit(1);
}
const char* aux_char;
string data;
while(1){
//--The host_service is for polling purposes. Must be called
//--often or the client will automatically disconnect from the
//--the host.
if(enet_host_service(client, &event, 1000) >= 0) {
if(event.type == ENET_EVENT_TYPE_RECEIVE) { // recv data
cout << ">Received data from: " << event.peer->incomingPeerID << ", message:$ - " << (const char*)event.packet->data << endl;
aux_char = (const char*)event.packet->data;
std::string str_data{aux_char};
enet_packet_destroy(event.packet); // free
}
}
//--Just for debugging, we don't need it in game
sleep(1);
//--Preparaing packet
data.clear();
data = name + " says " + to_string(4) + " is good number ";
ENetPacket* packet1 = enet_packet_create(data.c_str(), data.length(), ENET_PACKET_FLAG_RELIABLE);
if(!packet1) {
std::cout << ">Couldn't create packet" << std::endl;
exit(-1);
}
//--Send packet to the server
if(enet_peer_send(server, 0, packet1) < 0) {
std::cout << ">Couldn't send packet" << std::endl;
exit(-1);
}
//--Don't know why, without this everything explodes
enet_host_flush (client);
}
//--After game loop, to disconnect
enet_peer_disconnect (server, 0);
while(enet_host_service (client, &event, 5000) > 0) {
switch(event.type) {
case ENET_EVENT_TYPE_RECEIVE:
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
std::cout << ">Client is disconnected" << std::endl;
enet_deinitialize();
break;
}
}
enet_peer_reset(server);
std::cout << ">Force reset" << std::endl;
enet_deinitialize();
return 0;
}
Sever Side example of the problem I am experiencing:
Port: 4444
ip:127.0.0.1 connected, id: 0
received data from: 0 and data is: > nick says 4 is good number
received data from: 0 and data is: > nick says 4 is good number er
received data from: 0 and data is: > nick says 4 is good number er er
received data from: 0 and data is: > nick says 4 is good number er er er
received data from: 0 and data is: > nick says 4 is good number er er er er
ip:127.0.0.1 connected, id: 1
received data from: 0 and data is: > nick says 4 is good number er er er er
received data from: 0 and data is: > nick says 4 is good number er er er er
....
....
received data from: 1 and data is: > nath says 4 is good number er er er er
received data from: 0 and data is: > nick says 4 is good number er er er er
> Client id0 disconnected
> Client id0x1 disconnected
First Client:
Inser nickname: nick
Inser Port number: 4444
>Connected successfully
>Received data from: 0, message:$ - <0>nick says 4 is good number
>Received data from: 0, message:$ - <0>nick says 4 is good number er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
///the new client join the server
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Couldn't send packet
Second Client:
Inser nickname: nath
Inser Port number: 4444
>Connected successfully
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Received data from: 0, message:$ - <0>nick says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Received data from: 0, message:$ - <1>nath says 4 is good number er er er er
>Couldn't send packet
Can somebody explain what the issue is and how I can resolve it? Thank you!