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

Author Topic: Non-blocking SocketUDP behavior?  (Read 3402 times)

0 Members and 1 Guest are viewing this topic.

Mr. Moon

  • Newbie
  • *
  • Posts: 15
    • View Profile
Non-blocking SocketUDP behavior?
« on: September 13, 2010, 10:25:34 pm »
I'm currently making a P2P two-person co-op game.  This is my first experience with network programming.

I started with a simple example where two remote clients each move a square around onscreen, and are updated on the other's movements.

My question pertains to this code in my game loop:

Code: [Select]
       
// GAME LOOP
{
...
        // Has the player moved?
        bool moved = false;

        // Handle controls

        // Time since last frame
        float deltaTime = window.GetFrameTime();

        if (window.GetInput().IsKeyDown(sf::Key::Left))
        {
                mySquare.Move(-MOVE_SPEED * deltaTime, 0.f);
                moved = true;
        }
        else if (window.GetInput().IsKeyDown(sf::Key::Right))
        {
                mySquare.Move(MOVE_SPEED * deltaTime, 0.f);
                moved = true;
        }
        if (window.GetInput().IsKeyDown(sf::Key::Up))
        {
                mySquare.Move(0.f, -MOVE_SPEED * deltaTime);
                moved = true;
        }
        else if (window.GetInput().IsKeyDown(sf::Key::Down))
        {
                mySquare.Move(0.f, MOVE_SPEED * deltaTime);
                moved = true;
        }

        // SEND INFORMATION

        sf::Packet outPacket;

        outPacket << mySquare.GetPosition().x << mySquare.GetPosition().y;

        // Only send packets to the other player if I've updated my square's position.
        // NOTE: if I set this to "if (true)", the program works fine.
        if (moved)
        {
                std::stringstream ss;
                ss << "Moved";
                writeError(ss);

                if (socket.Send(outPacket, theirIP, port) != sf::Socket::Done)
                {
                        std::stringstream ss;
                        ss << "Couldn't send packet";
                        writeError(ss);
                }
        }

        // GET INFORMATION

        sf::Packet inPacket;

        if (socket.Receive(inPacket, theirIP, port) != sf::Socket::Done)
        {
                std::stringstream ss;
                ss << "Couldn't send packet";
                writeError(ss);
        }
        else
        {
                // Received a packet
                std::stringstream ss;
                ss << "Received a packet";
                writeError(ss);
        }

        float theirX = theirSquare.GetPosition().x;
        float theirY = theirSquare.GetPosition().y;

        if (!(inPacket >> theirX >> theirY))
        {
                std::stringstream ss;
                ss << "Invalid packet read";
                writeError(ss);
        }
        else
        {
                // Update the remote player's position
                theirSquare.SetPosition(theirX, theirY);
        }
...
}


If I set moved to always be "true" (i.e., I'm sending a packet at each iteration of the game loop regardless of whether or not there's a need to) the program works fine.  Otherwise, the other player's square never moves at all.  I know I'm sending packets, but it's as if the other client is never receiving them.

The single UDP socket I'm using is non-blocking.  My thought is the problem is caused because I'm calling Receive() more often than Send().  How does Receive() behave in this scenario?  And if I do have to match each Receive() call to a Send() call, how can I determine how often the other client is calling Send()?  Would it be better to use a blocking socket in a separate thread instead?