1
Network / Multiserver, crash on many connections
« on: February 23, 2009, 08:54:26 pm »
ok, thanks.
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
void sleep(float s)
{
clock_t end;
end = clock () + s*CLOCKS_PER_SEC;
while (clock() < end) ;
}
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <SFML/Network.hpp>
#include <SFML/System.hpp>
template <typename From, typename To>
To convert(const From & from)
{
std::stringstream stream;
stream << from;
To to;
stream >> to;
return to;
}
class ServerError
{
public:
std::string what;
ServerError(const std::string & er)
: what(er)
{
}
};
class Client : public sf::Thread
{
private:
sf::SocketTCP* socket;
sf::IPAddress* address;
sf::Int8 state;
public:
Client(sf::SocketTCP* m, sf::IPAddress*);
~Client();
virtual void Run();
static unsigned int getTotal();
sf::Int8 getState() const { return state; }
};
Client::Client(sf::SocketTCP* s, sf::IPAddress* a)
: socket(s), address(a), state(2)
{
}
Client::~Client()
{
delete socket;
delete address;
}
void Client::Run()
{
state = 1;
socket->Close();
state = 0;
}
class Server
{
private:
sf::Thread* gc_func;
sf::SocketTCP* socket;
sf::Mutex mutex_threads;
sf::Mutex mutex_lastcontainer;
std::map<std::string,std::clock_t> lastconnections;
std::vector<Client*> thread_clients;
sf::Int16 port;
bool listen;
bool gc_continue;
float gc_sleep_time;
float tbnc;
public:
Server();
void Init();
void Cleanup();
void Run();
friend void Server_GC(void*);
};
Server::Server() /* the program easy crash then gc_sleep_time = 0 */
: port(4029), gc_sleep_time(0), gc_continue(false), tbnc(0), socket(0), gc_func(0), listen(false)
{
}
void Server::Init()
{
using namespace sf;
gc_continue = true;
listen = true;
gc_func = new Thread(&Server_GC,this);
socket = new SocketTCP();
}
void Server_GC(void* data)
{
using namespace std;
Server* server = static_cast<Server*>(data);
while(server->gc_continue)
{
server->mutex_threads.Lock();
std::size_t size = server->thread_clients.size();
for(std::size_t i = 0; i < size;i++)
{
if(server->thread_clients[i]->getState() == 0)
{
delete server->thread_clients[i];
server->thread_clients.erase(server->thread_clients.begin()+i);
}
}
server->mutex_threads.Unlock();
server->mutex_lastcontainer.Lock();
for(map<string,clock_t>::iterator it = server->lastconnections.begin(); it != server->lastconnections.end(); it++)
{
if((*it).second < clock())
{
server->lastconnections.erase(it);
}
}
server->mutex_lastcontainer.Unlock();
sf::Sleep(server->gc_sleep_time);
}
}
void Server::Run()
{
using namespace sf;
using namespace std;
if(!socket->Listen(port))
{
throw ServerError("Could not start to listen at port " + convert<sf::Int16,std::string>(port));
}
gc_func->Launch();
while(listen)
{
SocketTCP* sock = new SocketTCP();
sf::IPAddress* address = new IPAddress();
if(socket->Accept(*sock, address) != Socket::Done)
{
delete sock;
delete address;
continue;
}
string ip = address->ToString();
mutex_lastcontainer.Lock();
if(lastconnections.end() != lastconnections.find(ip) && lastconnections[ip]*CLOCKS_PER_SEC > clock())
{
sock->Close();
delete sock;
delete address;
mutex_lastcontainer.Unlock();
continue;
}
lastconnections[ip] = clock()+CLOCKS_PER_SEC*tbnc;
mutex_lastcontainer.Unlock();
cout << "Client connected: " << address->ToString() << endl;
Lock mutex(mutex_threads);
thread_clients.push_back(new Client(sock,address));
thread_clients[thread_clients.size()-1]->Launch();
}
while(thread_clients.size() >= 0)
{
sf::Sleep(1);
}
gc_continue = false;
}
void Server::Cleanup()
{
gc_func->Wait();
delete gc_func;
}
int main(int argc, char args[])
{
using namespace std;
try
{
Server* server = new Server();
cout << "Init\n";
server->Init();
cout << "Running...\n";
server->Run();
cout << "Cleaning\n";
server->Cleanup();
cout << "Finish\n";
}
catch(...)
{
cerr << "Error..\n";
return 1;
}
return 0;
}
#include <iostream>
#include <string>
#include <vector>
#include <SFML/Network.hpp>
#include <SFML/System.hpp>
class ServerError
{
public:
std::string what;
ServerError(const std::string & er)
: what(er)
{
}
};
class Client : public sf::Thread
{
private:
sf::SocketTCP* socket;
sf::IPAddress* address;
sf::Int8 state;
public:
Client(sf::SocketTCP* m, sf::IPAddress*);
~Client();
virtual void Run();
sf::Int8 getState() const { return state; }
};
Client::Client(sf::SocketTCP* s, sf::IPAddress* a)
: socket(s), address(a), state(2)
{
}
Client::~Client()
{
delete socket;
delete address;
}
void Client::Run()
{
this->state = 1;
sf::Packet packet;
packet << "Hello";
this->socket->Send(packet);
packet.Clear();
this->socket->Receive(packet);
this->socket->Close();
this->state = 0;
}
class Server
{
private:
sf::Thread* gc_func;
unsigned int run_at_port;
unsigned long long int max_clients;
bool keep_listen;
std::vector<Client*> thread_clients;
sf::Mutex mutex_clients;
bool gc_continue;
float gc_sleep_time;
public:
Server();
void Init();
void Cleanup();
void Run();
void gc();
friend void Server_GC(void*);
};
Server::Server()
{
run_at_port = 4029;
max_clients = 10;
gc_sleep_time = 0;
gc_continue = false;
}
void Server::Init()
{
gc_func = 0;
gc_func = new sf::Thread(&Server_GC,this);
gc_continue = true;
gc_func->Launch();
keep_listen = true;
}
void Server_GC(void* data)
{
Server* server = static_cast<Server*>(data);
while(server->gc_continue)
{
std::size_t size = server->thread_clients.size();
for(std::size_t i = 0; i < size;i++)
{
if(server->thread_clients.at(i)->getState() == 0)
{
server->mutex_clients.Lock();
delete server->thread_clients.at(i);
server->thread_clients.erase(server->thread_clients.begin()+i);
server->mutex_clients.Unlock();
}
}
sf::Sleep(server->gc_sleep_time);
}
}
void Server::Run()
{
using namespace sf;
SocketTCP conn;
if(!conn.Listen(this->run_at_port))
{
throw ServerError("mohaah");
}
while(keep_listen)
{
SocketTCP* sock = new SocketTCP();
sf::IPAddress* address = new IPAddress();
this->mutex_clients.Lock();
thread_clients.push_back(new Client(sock,address));
thread_clients[thread_clients.size()-1]->Launch();
this->mutex_clients.Unlock();
while(thread_clients.size() >= max_clients)
{
}
}
while(thread_clients.size() >= 0)
{
sf::Sleep(1);
}
conn.Close();
}
void Server::Cleanup()
{
if(gc_func != 0)
{
gc_func->Terminate();
delete gc_func;
}
}
void Connecter(void* a)
{
while(true)
{
std::cout << "Mohaha";
sf::SocketTCP socket;
if (socket.Connect(4029, "127.0.0.1") != sf::Socket::Done)
{
continue;
}
sf::Packet packet;
packet << "hellow";
socket.Send(packet);
socket.Close();
//break;
sf::Sleep(0);
}
}
int main(int argc, char args[])
{
try
{
sf::Thread connecter(&Connecter);
connecter.Launch();
Server* server = new Server();
server->Init();
server->Run();
server->Cleanup();
}
catch(ServerError & a)
{
std::cerr << a.what << std::endl;
throw;
}
catch(std::exception & a)
{
std::cerr << a.what() << std::endl;
throw;
}
catch(...)
{
return 1;
}
return 0;
}
while(true)
{
sf::SocketTCP socket;
if (socket.Connect(4029, "127.0.0.1") != sf::Socket::Done)
{
continue;
}
sf::Packet packet;
packet << "hello";
socket.Send(packet);
socket.Close();
}