SFML community forums
Help => Network => Topic started by: wilbefast on September 09, 2010, 02:07:38 pm
-
This is probably a very stupid question, but bear with me.
I'm trying to build my first ever network game. For this I need to be able to send many different kinds of "message" between the computers. For instance:
- connection request
- you have x time left before you lag-out
- object y is at position z
- object t has been created at position u
- etc
So I don't know what my packet will contain until I open it, but until I open it I don't know what it will contain :(
My idea was to give each packet a sort of "header" which lets the receiver know how to open it. The header would always be, say, a short unsigned integer.
I know this is possible if I'm just sending bytes but it would be rather fiddly. Is there a way of implementing this kind of stuff with SFML packets?
Thanks,
William
-
Sure, there's no problem
// sending
sf::Packet packet;
packet << header << ... specific data ... ;
socket.Send(packet);
// receiving
sf::Packet packet;
socket.Receive(packet);
sf::Uint8 header;
packet >> header;
switch (header)
{
case ConnectionRequest:
packet >> ... specific data ...;
connect(...);
break;
case MoveObject:
packet >> ... specific data ...;
moveObject(...);
break;
...
}
-
Thanks! That's really helpful :D
-
Hmmm... :?
I've been able to get my the two machines (one real, one virtual) connected, but sending packets doesn't seem to be working somewhere along the line...
192.168.56.1 is the address of the virtual machine (192.168.56.101 is the address of the real one) in the virtual network. I've managed to send and receive via UDP, but TCP doesn't seem to like me very much. What's wrong with this picture :(
#include "lobby.h"
using namespace std;
int lobby_join(sf::RenderWindow& window)
{
bool connected = false;
//Get server IP Address
sf::IPAddress serverIP = "192.168.56.1";
//Load Font
sf::Font font;
if(!font.LoadFromFile("content/fonts/Courier_New.ttf"))
cout << "Unable to load font\n";
//Create String
sf::String message("attempting to connect:\nPress 'Esc' to cancel\n", font, 50);
message.SetColor(sf::Color(0, 0, 0));
message.SetPosition(32,32);
//Create socket: pipeline to server
sf::SocketTCP server;
server.SetBlocking(false);
//Check the validity of the address
if(!serverIP.IsValid())
cout << serverIP << " is invalid\n";
//create buffers
sf::Packet packet;
sf::Uint8 header;
//Create Event handler called 'event'
sf::Event event;
//start the main loops
bool running = true;
while(running)
{
//Read each Event, store in 'event' and treat
while (window.GetEvent(event))
{
switch (event.Type)
{
//Window closed
case sf::Event::Closed:
running = false; break;
//Key press
case sf::Event::KeyPressed:
switch (event.Key.Code)
{
//ESCAPE key
case (sf::Key::Escape):
running = false; break;
//all other cases
default:
send(PING,server);
cout << "Sent ping to " << serverIP << endl;
break;
}
break;
//all other cases
default: break;
}
}
//attempt to connect to the address if not already connected
if(!connected)
{
if (server.Connect(PORT, serverIP) == sf::Socket::Done)
{
cout << "Connected to server " << serverIP << endl;
connected = true;
message.SetText("Connected: Waiting\nfor server to start\nPress 'Esc' to disconnect\n");
}
}
//try to retrieve a packet from the host if connected
else if (server.Receive(packet) == sf::Socket::Done)
{
//interpret packet based on header
packet >> header;
switch(header)
{
//
case PLAY:
printf("The host has started the game\n");
//play(...);
break;
//host has left
case QUIT:
printf("The host has left the lobby\n");
running = false; break;
default:
printf("Unknown packet type %d received\n",header); break;
}
}
//Clear the Windows
window.Clear(sf::Color(0, 200, 0));
//Draw the the message
window.Draw(message);
//Redraw the Window
window.Display();
}
//Close the socket
server.Close();
printf("Stopped joining\n\n");
return EXIT_SUCCESS;
}
int lobby_host(sf::RenderWindow& window)
{
bool connected = false;
//Load Font
sf::Font font;
if(!font.LoadFromFile("content/fonts/Courier_New.ttf"))
cout << "Unable to load font" << endl;
//Create String
sf::String message("Waiting for connections:\nPress 'Enter' to start\nPress 'Esc' to cancel", font, 50);
message.SetColor(sf::Color(0, 0, 0));
message.SetPosition(32,32);
//Create server socket
sf::SocketTCP server;
server.SetBlocking(false);
// Listen to a port for incoming connections
if (server.Listen(PORT))
std::cout << "Listening to port " << PORT << ", waiting for connections" << std::endl;
else
std::cout << "Can't listen to port " << PORT << std::endl;
//Create client socket
sf::IPAddress clientIP;
sf::SocketTCP client;
//Create buffers
sf::Packet packet;
sf::Uint8 header;
//Create Event handler called 'event'
sf::Event event;
//start the main loops
bool running = true;
while(running)
{
//Read each Event, store in 'event' and treat
while (window.GetEvent(event))
{
switch (event.Type)
{
//Window closed
case sf::Event::Closed:
running = false; break;
//Key press
case sf::Event::KeyPressed:
switch (event.Key.Code)
{
//ESCAPE key
case (sf::Key::Escape):
send(QUIT,client);
running = false;
break;
//RETURN key
case (sf::Key::Return):
send(PLAY,client);
///FIXME
//play(...);
break;
//all other cases
default:
send(PING,client);
printf("Sent ping to client\n");
break;
}
break;
//all other cases
default: break;
}
}
//Check for connections if not already connected
if (connected == false)
{
if (server.Accept(client, &clientIP) == sf::Socket::Done)
{
message.SetText("Client connected:\nPress 'Enter' to start\nPress 'Esc' to cancel\n");
std::cout << "Client connected : " << clientIP << std::endl;
}
}
//Check for packets if connected
else if (client.Receive(packet) == sf::Socket::Done)
{
//interpret packet based on header
packet >> header;
switch(header)
{
default:
printf("unkown packet type %d received\n", header);
break;
}
}
//Clear the Windows
window.Clear(sf::Color(0, 0, 200));
//Draw the the message
window.Draw(message);
//Redraw the Window
window.Display();
}
//Close the sockets
server.Close();
client.Close();
printf("Stopped hosting\n\n");
return EXIT_SUCCESS;
}
void send(int message, sf::SocketTCP target)
{
sf::Packet packet;
packet << (sf::Uint8) message;
target.Send(packet);
}
PS - I see you are from France!
Feel free to reply in French if you want - I've been learning for 14 years and have been studying Informatique at Montpellier for the last 2 8)
I like writing my comments in English though...
William
-
I don't see anything wrong in your code.
You can try with blocking sockets and see if it works better. You can also try to connect to localhost, to make sure that your network environment is not involved in the bug.
Feel free to reply in French if you want
This is an english forum, so we'll stick to english so that other users can understand the discussion ;)
-
int lobby_host(sf::RenderWindow& window)
{
...
bool connected = false;
...
//Check for connections if not already connected
if (connected == false)
{
if (server.Accept(client, &clientIP) == sf::Socket::Done)
{
message.SetText("Client connected:\nPress 'Enter' to start\nPress 'Esc' to cancel\n");
std::cout << "Client connected : " << clientIP << std::endl;
}
}
...
Maybe try to change the connected boolean to true here ? :wink:
-
Good find :D
Unfortunately it doesn't fix the problem :( I wonder why it should work for UDP and normal command-line pings, just not for TCP... there must be something wrong with the code somewhere :?
-
Give us the minimal code (see my signature) of the client and the server. I could test it here.
-
Thanks Mindiell. Okay so... minimum code. You're asking me to chop up my babies!?
This should compile with the code at the top of the file. Make sure you changer SERVER to the ip you're connecting to:
http://pastebin.com/QD9cJukj
Okay, so there's still a lot there... let me know if it's not "minimum" enough :oops:
edit: yeah - it's definately a problem with my code or with the packets: I did a test of my network setup using the example code from this page
http://www.sfml-dev.org/tutorials/1.6/network-sockets.php
and everything works fine for TCP messages as well as UDP ones.
-
Arg !
I have to switch from SFML 2 to SFML 1.7 to test your code :/
I'll give you more infos...
-
Sorry :? I tend to use stable builds when I can. What's changing for 2.0?
-
Gasp, a lot of things. But 2.0 is almost stable, nothing very difficult to use. The only thing is that Laurent is not releasing it because he wants to finish it properly before.