I'm at the point in my game where I want to start doing networking to play with my friends. My server and client code is minimal, and they're not even sending or receiving from each other yet. For now, I'm controlling the environment by only allowing one client to connect, and I'm running the client and server on the same laptop.
The server/client code is run in a separate thread than all my game code. The thread first asks what the user is, a sever or a client, then it goes from there.
The problem is, once the client connects to the server, the server's game frame rate drops drastically, and only sometimes the client does too. But mostly just the server. I'm not sending anything back and forth yet, I only allow the client to connect to the server.
Right when I disconnect the client, the server then runs perfectly normal. Its frame rate only drops when connected.
Here is the entire code for the server and clients.
void runNet(void* UserData)
{
SoccerLevelsClass* obj = static_cast<SoccerLevelsClass*>(UserData);
obj->netQuit=false;
obj->netType = 0;
cout<<"What are you? 0 for server, 1 for client : ";
cin>>obj->netType; //store network type( 0 for sever, 1 for client)
cout<<"\n";
// start of server code
if(obj->netType==0)
{
// Create a socket to listen to new connections
sf::TcpListener listener;
listener.listen(2000);
// Create a list to store the future clients
std::vector<sf::TcpSocket*> clients;
// Create a selector
sf::SocketSelector selector;
// Add the listener to the selector
selector.add(listener);
listener.setBlocking(false);
// Endless loop that waits for new connections
while (obj->netQuit==false)
{
// cout<<"waiting.\n";
// Make the selector wait for data on any socket
if (selector.wait(sf::milliseconds(1)))
{
cout<<"done waiting. listening.\n";
// Test the listener
if (selector.isReady(listener))
{
cout<<"trying to add client.\n";
// The listener is ready: there is a pending connection
sf::TcpSocket* client = new sf::TcpSocket;
if (listener.accept(*client) == sf::Socket::Done)
{
client->setBlocking(false);
// Add the new client to the clients list
clients.push_back(client);
// Add the new client to the selector so that we will
// be notified when he sends something
selector.add(*client);
cout<<"added client.\n";
}
else
{
// Error, we won't get a new connection, delete the socket
delete client;
}
}
else
{
cout<<"testing clients.\n";
// The listener socket is not ready, test all other sockets (the clients)
for (std::vector<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
{
sf::TcpSocket& client = **it;
if (selector.isReady(client))
{
/*
// The client has sent some data, we can receive it
sf::Packet packet;
packet << obj->playerOneStruct;
client.send(packet);
packet.clear();
if (client.receive(packet) == sf::Socket::Done)
{
// ...
}
*/
}
}
}
}
}
}// end of server code
// start of client code
if(obj->netType==1)
{
sf::IpAddress server;
do
{
std::cout << "Type the address or name of the server to connect to: ";
std::cin >> server;
}
while (server == sf::IpAddress::None);
cout<<"here1\n";
sf::TcpSocket socket;
while(socket.connect(server,2000) != sf::Socket::Done)
{
}
cout<<"connected.\n";
socket.setBlocking(false);
while(obj->netQuit==false)
{
/*
sf::Packet packet;
sf::Socket::Status status = socket.receive(packet);
if (status == sf::Socket::Done)
{
packet >> obj->playerOneStruct;
cout<<"herh\n";
}
else if(status == sf::Socket::NotReady)
{
cout<<"not ready.\n";
}
else if(status == sf::Socket::Disconnected)
{
cout<<"disconnected.\n";
}
else if(status == sf::Socket::Error)
{
cout<<"error.\n";
}
*/
}
}// end of client code
}// end of thread function
I commented out all the code I thought would cause my server to lag, but it's still lagging. I don't understand why it's causing my game to drop its frame rate, especially when it runs in a separate thread.
So here are my questions:
1. Is this code okay? Do you see anything that would make it lag the computer?
2.Do you think it's because I'm running the client and server on the same machine? Could that be the reason why the frame rate is dropping?
Thank You
What you basically have in your server portion is this:
while (obj->netQuit==false)
{
selector.wait(sf::milliseconds(1))
// Other stuff that probably takes less than 1 millisecond
}
If you loop on a blocking call, the application will.... block a lot. I highly doubt that your other code requires more than 1 millisecond in total to run, so that call is what takes up almost all the time which makes the difference so prominent. Your server thread ends up effectively blocking for 99.999% of the time (and this blocking can have many manifestations from simple sleeping to busy waiting etc.), hence the "low frame rate" if you can even consider a frame rate for a thread that blocks that much...
If you remove the sf::milliseconds(1) and let the selector return immediately (default timeout value is sf::Time::Zero) you will see what I mean.
Also... you don't have to set your listener or client sockets to non-blocking if you are already using a selector. This can make sense in very advanced use cases, but in general it is not required.
If this wasn't the problem, then you will have to post more code. It is hard to tell from the code you provided whether this is a code-related issue or something completely different.