I am currently working on SpaceInvaders with the ability for a second executable to act as client as watch me play.
I am following tutorials and documentation online to get UDP packets working to send positional updates for my spaceship. I am getting the error
failed to read from player data packet! when client connects. This is what I have so far -
void createUdpServer(unsigned short port) { // send data to client
// Create a socket to receive a message from anyone
sf::UdpSocket socket;
sf::IpAddress local = sf::IpAddress::getLocalAddress(); // Currently 127.0.0.1 localhost
sf::IpAddress receiver = sf::IpAddress::getLocalAddress();
socket.setBlocking(false);
// I was figuring out and arranging according to example.. set socket non blocking
// Listen to messages on the specified port
if (socket.bind(port) != sf::Socket::Done) // You bind once
return;
std::cout << "Server is listening to port " << port << ", waiting for a connection... " << std::endl;
// Wait for a message
char in[128];
std::size_t received;
sf::IpAddress sender;
//unsigned short senderPort; we will be receiving and sending data on sa,e port
sf::SocketSelector selector;
selector.add(socket);
if (selector.wait(sf::milliseconds(10.f))) { // times out after 10ms
if (selector.isReady(socket)) {
if (socket.receive(in, sizeof(in), received, sender, port) != sf::Socket::Done) // blocking
return;
std::cout << "Message received from client " << sender << ": \"" << in << "\"" << std::endl;
}
}
// Sends connection established to client
/*
const char out[] = "Connection with server established!";
if (socket.send(out, sizeof(out), sender, port) != sf::Socket::Done)
return;
*/
// acknowledgement of packets
float playerXPosition = player->getPosition().x;
float playerYPosition = player->getPosition().y;
sf::Packet playerData;
playerData << playerXPosition << playerYPosition;
socket.send(playerData, sender, port);
//const char out[] = "";
//if (socket.send(out, sizeof(out), sender, port) != sf::Socket::Done)
// return;
}
void runUdpClient(unsigned short port) { // receive data from server
// Ask for the server address
server = "127.0.0.1";
/*
if (server == sf::IpAddress::None)
do
{
std::cout << "Type the address or name of the server to connect to: ";
std::cin >> server;
} while (server != sf::IpAddress::None);
*/
// Create a socket for communicating with the server
sf::UdpSocket socket;
sf::IpAddress recipient = sf::IpAddress::getLocalAddress();
char data[100] = "Connection with client established!";
if (socket.send(data, 100, server, port) != sf::Socket::Done)
{
// error...
}
// Think about putting this globally
sf::SocketSelector selector;
selector.add(socket);
if (selector.wait(sf::seconds(0.1f))) { // not enough time for server to be created with 0.1f
// received something
if (selector.isReady(socket)) {
// Wait for a message
char in[128];
std::size_t received;
sf::IpAddress sender;
sf::Packet playerData;
float playerXPosition;
float playerYPosition;
socket.receive(playerData, sender, port);
if (playerData >> playerXPosition && playerData >> playerYPosition) { // if you are able to read
player->setPosition(playerXPosition, playerYPosition);
}
else {
std::cout << "Error - failed to read from player data packet!" << std::endl;
}
//unsigned short senderPort;
//if (socket.receive(in, sizeof(in), received, sender, port) != sf::Socket::Done)
// return;
//std::cout << "Message received from server " << sender << ": \"" << in << "\"" << std::endl;
}
// this shouldn't be here, receive stuff should go on client, server just sends
}
else {
// timeout reached, nothing was received
}
// prediction
// bullet
}
I am instancing the player in both client and server. The position of the player is controlled by the keyboard, in client it should receive updates from the server and move accordingly from x and y values.