Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Networked program runs really SLOW  (Read 20992 times)

0 Members and 1 Guest are viewing this topic.

Pwndja

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Networked program runs really SLOW
« on: February 02, 2008, 06:13:08 am »
so i made a quick little pong game and made it networked, and it runs fine when i run the client and the server on one computer but when i run it on another computer on my local network it becomes horribly slow... we are talk about one pixle every five seconds (Thats really really slow lol)
I was wondering if there is some trick code that i am leaving out that makes the networked code run faster... kick of like the OptimizeForNonOpenGL() line with renderedwindow.

Any feed back on why my code runs soo slow over a local network would be great.

I know that IP/TCP is slower than UDP but i didn't think that sending the small packet like i am across would cause things to clog up as much as it does.



Here is my code for the pong game:

Code: [Select]


////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>

#define _CRT_SECURE_NO_WARNINGS

#define paddle_speed 2
#define ballspeed 0.3

struct data
{
float x;
float y;
int message;
};


sf::Packet& operator <<(sf::Packet& Packet, const data& C)
{
    return Packet << C.x << C.y << C.message;
}

sf::Packet& operator >>(sf::Packet& Packet, data& C)
{
return Packet >> C.x >> C.y >> C.message;
}

////////////////////////////////////////////////////////////
/// Create a client and connect it to a running server
///
////////////////////////////////////////////////////////////
void DoClientTCP(unsigned short Port)
{
sf::RenderWindow app( sf::VideoMode( 800, 600 ),"Client", sf::Style::Resize );
app.SetBackgroundColor( sf::Color(0,0,0) );


sf::Image img;
sf::Image ball;
img.LoadFromFile( "left_paddle.png" );
ball.LoadFromFile( "ball.bmp" );

sf::Sprite spr[2];
sf::Sprite sprball;

spr[0].SetImage( img );
spr[0].SetPosition( 10.f , 10.f );

spr[1].SetImage( img );
spr[1].SetPosition( 790.f - spr[1].GetWidth(), 10.f );
spr[1].FlipX( true );

sprball.SetImage( ball );
sprball.SetPosition( 400.f, 300.f );

// Ask for server address
sf::IPAddress ServerAddress;
do
{
std::cout << "Type address or name of the server to connect to : ";
std::cin  >> ServerAddress;
}
while (!ServerAddress.IsValid());

// Create a TCP socket for communicating with server



sf::SocketTCP Client;

// Connect to the specified server
if (!Client.Connect(Port, ServerAddress))
return;
std::cout << "Connected to server " << ServerAddress << std::endl;

// Receive a message from the client
int ToSend = 0;
int Message = 0;
//std::size_t Received;
float ball_x = 400.f, ball_y = 300.f;
float ball_Xdelta = ballspeed, ball_Ydelta = ballspeed;

bool key = false;
bool running = true;
while( running )
{

if( app.GetInput().IsKeyDown( sf::Key::Down ) )
{
ToSend = 1;
spr[1].SetTop( spr[1].GetTop() + paddle_speed );
}

if( app.GetInput().IsKeyDown( sf::Key::Up ) )
{
ToSend = 2;
spr[1].SetTop( spr[1].GetTop() - paddle_speed );
}
if( !app.GetInput().IsKeyDown( sf::Key::Up ) && !app.GetInput().IsKeyDown( sf::Key::Down ) )
{
ToSend = 0;
}
if( app.GetInput().IsKeyDown( sf::Key::Escape ) )
{
running = false;
}
data send;
send.message = ToSend;
send.x = 0.0f;
send.y = 0.0f;
sf::Packet sendPacket;
sendPacket << send;
Client.Send( sendPacket );

//if (Client.Receive(Message, sizeof(Message), Received) != sf::Socket::Done)
//return;
sf::Packet dataPacket;
if( Client.Receive( dataPacket ) != sf::Socket::Done )
return;
data dat;
if( !(dataPacket >> dat) )
{
std::cout << "ERROR" << std::endl;
}
ball_x = dat.x;
ball_y = dat.y;
Message = dat.message;

// move other players paddle
if( Message == 1 )
{
spr[0].SetTop( spr[0].GetTop() + paddle_speed );
}
if( Message == 2 )
{
spr[0].SetTop( spr[0].GetTop() - paddle_speed );
}

ball_x += ball_Xdelta;
ball_y += ball_Ydelta;

sprball.SetPosition( ball_x, ball_y );

app.Draw( sprball );
app.Draw( spr[1] );
app.Draw( spr[0] );

app.Display();
}

// Close the socket when we're done
Client.Close();
}


////////////////////////////////////////////////////////////
/// Launch a server and wait for incoming connections
///
////////////////////////////////////////////////////////////
void DoServerTCP(unsigned short Port)
{
sf::RenderWindow app( sf::VideoMode( 800, 600 ),"Server", sf::Style::Resize );
app.SetBackgroundColor( sf::Color(0,0,0) );


sf::Image img;
sf::Image ball;
img.LoadFromFile( "left_paddle.png" );
ball.LoadFromFile( "ball.bmp" );

sf::Sprite spr[2];
sf::Sprite sprball;

spr[0].SetImage( img );
spr[0].SetPosition( 10.f , 10.f );

spr[1].SetImage( img );
spr[1].SetPosition( 790.f - spr[1].GetWidth(), 10.f );
spr[1].FlipX( true );

sprball.SetImage( ball );
sprball.SetPosition( 400.f, 300.f );

// Create a TCP socket for communicating with clients



sf::SocketTCP Server;

// Listen to a port for incoming connections
if (!Server.Listen(Port))
return;
std::cout << "Server is listening to port " << Port << ", waiting for connections... " << std::endl;

// Wait for a connection
sf::IPAddress ClientAddress;
sf::SocketTCP Client;
if (Server.Accept(Client, &ClientAddress) != sf::Socket::Done)
return;
std::cout << "Client connected : " << ClientAddress << std::endl;

// Send a message to the client
int ToSend = 0;
int Message = 0;
std::size_t Received;
float ball_x = 400.f, ball_y = 300.f;
float ball_Xdelta = ballspeed, ball_Ydelta = ballspeed;

bool key = false;
bool running = true;

while(running)
{
if( app.GetInput().IsKeyDown( sf::Key::S ) )
{
ToSend = 1;
spr[0].SetTop( spr[0].GetTop() + paddle_speed );
}

if( app.GetInput().IsKeyDown( sf::Key::W ) )
{
ToSend = 2;
spr[0].SetTop( spr[0].GetTop() - paddle_speed );
}
if( !app.GetInput().IsKeyDown( sf::Key::W ) && !app.GetInput().IsKeyDown( sf::Key::S ) )
{
ToSend = 0;
}
if( app.GetInput().IsKeyDown( sf::Key::Escape ) )
{
running = false;
}
data dat;
dat.x = ball_x;
dat.y = ball_y;
dat.message = ToSend;
sf::Packet dataPacket;
dataPacket << dat;
Client.Send( dataPacket );
//Client.Send( ToSend, sizeof(ToSend) );

sf::Packet receivePacket;
if (Client.Receive(receivePacket) != sf::Socket::Done)
return;
data rec;
receivePacket >> rec;

Message = rec.message;

//collision statements here
if( sprball.GetTop() < 0 || sprball.GetTop() > 600 )
{
ball_Ydelta = -ball_Ydelta;
}

if( sprball.GetLeft() + (sprball.GetHeight() / 2) < 20 && (spr[0].GetTop() < sprball.GetTop() +(sprball.GetHeight() / 2) && sprball.GetTop()  + (sprball.GetHeight() / 2) < spr[0].GetTop() + spr[0].GetHeight() ) )
{
ball_Xdelta = -ball_Xdelta;
}
if( sprball.GetLeft() + (sprball.GetHeight() / 2) > 780 && ( spr[1].GetTop() < sprball.GetTop() + (sprball.GetHeight() / 2) && sprball.GetTop() + (sprball.GetHeight() / 2) < spr[1].GetTop() + spr[1].GetHeight() ) )
{
ball_Xdelta = -ball_Xdelta;
}
//end collision statements

// move other players paddle
if( Message == 1)
{
spr[1].SetTop( spr[1].GetTop() + paddle_speed );
}
if( Message == 2 )
{
spr[1].SetTop( spr[1].GetTop() - paddle_speed );
}

ball_x += ball_Xdelta;
ball_y += ball_Ydelta;

sprball.SetPosition( ball_x, ball_y );

app.Draw( sprball );
app.Draw( spr[1] );
app.Draw( spr[0] );

app.Display();
}

// Close the sockets when we're done
Client.Close();
Server.Close();
}

T.T.H.

  • Full Member
  • ***
  • Posts: 112
    • View Profile
Networked program runs really SLOW
« Reply #1 on: February 02, 2008, 09:41:39 am »
After having a short look on your code I'd say the following:

Both client and server are sending and waiting for a packet each frame and I assume the sockets are blocking by default. So all in all I guess both your programs are mostly waiting for each other due to the Client.Receive and Server.Receive calls - resulting in horrible frame rates.

You might set both sockets to non-blocking so there is no more waiting for each other. But then you have to verify that your Receive functions actually received something reasonable before you further process that data you want to receive.

Pwndja

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Does help
« Reply #2 on: February 03, 2008, 05:06:03 am »
I tried adding in Client.SetBlocking( false ); but that just makes the program stop running right away, so it doesn't help... if there is a particular spot i need to place it that would be help full to know... I tried placing it right above the while loop

Client.SetBlocking( false );
while( running )
{
.
.
.
}

maybe using udp would be better but I really dont think TCP should go this slow.

Thank you for your suggestions. Anymore ideas are welcome.

zarka

  • Jr. Member
  • **
  • Posts: 81
    • View Profile
Re: Does help
« Reply #3 on: February 03, 2008, 11:58:55 am »
Quote from: "Pwndja"
I tried adding in Client.SetBlocking( false ); but that just makes the program stop running right away, so it doesn't help... if there is a particular spot i need to place it that would be help full to know... I tried placing it right above the while loop

Client.SetBlocking( false );
while( running )
{
.
.
.
}

maybe using udp would be better but I really dont think TCP should go this slow.

Thank you for your suggestions. Anymore ideas are welcome.


well of course it will exit almost instantly when you are using non blocking sockets ... you tell it to!

Code: [Select]

sf::Packet receivePacket;
if (Client.Receive(receivePacket) != sf::Socket::Done)
     return;


because if you are using non blocking sockets it wont wait until it receives a packet to return .. and since it didn't receive anything it wouldn't return that it is done ...

if you want to keep using blocking sockets i suggest  you put your networking code in a thread so the main logic/rendering thread wont be affected by the network stalls ...
//Zzzarka

e_barroga

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Networked program runs really SLOW
« Reply #4 on: August 27, 2008, 04:00:39 am »
Instead of sending a message every single frame, send messages on keystrokes.

When the key is pressed, send the message to start moving. When it is released send the message to stop moving.