I tried to make a minimal version. Should work.. somewhat ^^;
I'm not sure if this illustrates the problem properly but... if several clients are connected the server starts to chug.
Server Code
#include <SFML/Network.hpp>
#include <iostream>
#include <deque>
struct PlayerCharacter
{
int x;
int y;
};
struct User
{
sf::TcpSocket* socket;
PlayerCharacter* player;
int id;
};
void receivePacket(sf::Packet *packet, PlayerCharacter *pc, std::deque<std::string> *chat)
{
int packetid;
*packet >> packetid;
//Updates character location
if (packetid == 2)
{
int temp_xchange;
*packet >> temp_xchange;
int temp_ychange;
*packet >> temp_ychange;
int packet_number;
*packet>> packet_number;
pc->x = (pc->x + temp_xchange);
pc->y = (pc->y + temp_ychange);
std::cout << pc->x << "_" << pc->y << "_" << packet_number << std::endl;
}
}
void updateClients(std::deque<std::string> *chat, std::vector<User> *clients)
{
sf::Packet out_packet;
//If there is chat in the queue. It will pop and send it to the clients.
if (chat->size() > 0)
{
out_packet << 1;
std::string temp_string;
temp_string = chat->front();
chat->pop_front();
out_packet << temp_string;
for (unsigned int i = 0; i < clients->size(); i++)
{
clients->at(i).socket->send(out_packet);
}
}
//Sends player data to other players
for (unsigned int i = 0; i < clients->size(); i++)
{
out_packet << 2;
out_packet << clients->at(i).id;
out_packet << clients->at(i).player->x << clients->at(i).player->y;
clients->at(i).socket->send(out_packet);
}
}
int main()
{
std::deque<std::string> chatLog;
sf::TcpListener listener;
listener.listen(7338);
std::vector<User> clients;
sf::SocketSelector selector;
selector.add(listener);
while (true)
{
if (selector.wait())
{
if (selector.isReady(listener))
{
sf::TcpSocket* client = new sf::TcpSocket;
if (listener.accept(*client) == sf::Socket::Done)
{
int temp_id;
bool unique_id;
do
{
unique_id = true;
temp_id = rand() % 10000000;
for (unsigned int i = 0; i < clients.size(); i++)
{
if (temp_id == clients[i].id)
{
unique_id = false;
}
}
}
while(unique_id == false);
PlayerCharacter temp_player;
User temp_user = {client, &temp_player, temp_id};
clients.push_back(temp_user);
std::cout << "New client connected: " << client->getRemoteAddress() << std::endl;
selector.add(*client);
}
else
{
delete client;
}
}
else
{
for (unsigned int i = 0; i < clients.size(); i++)
{
if (selector.isReady(*clients.at(i).socket))
{
sf::Packet packet;
sf::Socket::Status status = clients.at(i).socket->receive(packet);
if (status == sf::Socket::Done)
{
receivePacket(&packet,clients.at(i).player, &chatLog);
}
else if (status == sf::Socket::Disconnected)
{
std::cout<<"Client disconnected."<<std::endl;
selector.remove(*clients.at(i).socket);
clients.at(i).socket->disconnect();
delete(&clients.at(i).socket);
clients.erase(clients.begin()+ i);
i--;
std::cout<<"Clients currently connected: "<<clients.size()<<std::endl;
}
}
}
}
}
updateClients(&chatLog, &clients);
}
return 0;
}
And here's the client code that I threw together..
#include <SFML/Network.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
#include <sstream>
#include <deque>
struct PlayerCharacter
{
int id;
int x;
int y;
};
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Eris v0.001");
window.setFramerateLimit(30);
sf::TcpSocket socket;
socket.setBlocking(false);
sf::Packet in_packet;
std::vector<PlayerCharacter> playerlist;
int packetnumber = 0;
sf::IpAddress server("localhost");
if (socket.connect(server, 7338) != sf::Socket::Done)
{
//something
}
while (window.isOpen())
{
if (socket.receive(in_packet) == sf::Socket::Done)
{
int packet_id;
in_packet >> packet_id;
if (packet_id == 2)
{
int player_id;
in_packet >> player_id;
std::cout<<player_id<<"_";
int temp_x;
in_packet >> temp_x;
std::cout<<temp_x<<"_";
int temp_y;
in_packet >> temp_y;
std::cout<<temp_y<<"_"<<std::endl;
bool exists = false;
for (unsigned int i = 0; i < playerlist.size(); i++)
{
if (playerlist[i].id == player_id)
{
exists = true;
playerlist[i].x = temp_x;
playerlist[i].y = temp_y;
}
}
if (exists == false)
{
PlayerCharacter temp_player = {player_id, temp_x, temp_y};
playerlist.push_back(temp_player);
}
}
}
packetnumber++;
//sends location data
sf::Packet out_packet;
out_packet << 2 << 0 << 0 << packetnumber;
std::cout<<"SENT:" << packetnumber << std::endl;
socket.send(out_packet);
window.clear();
window.display();
}
return 0;
}