SFML网络 - 通过UDP协议发送数据包时出错

时间:2016-12-11 03:23:01

标签: c++ sockets network-programming udp sfml

我对SFML网络很陌生,并且已经有很长一段时间用于pong克隆了。我写了两个程序:客户端和服务器。我的问题是两者似乎没有在彼此之间正确地发送/接收数据。我检查过,我的端口正确绑定,我的数据包不大于最大数据报大小。但是,当我检查socket.send(...)Socket::Done的状态时,它会发现数据未发送。有什么我做错了吗?

客户端:

#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <ctime>
#include <iostream>
#include <sstream>

using namespace sf;
using namespace std;


template <typename T>
string NumberToString ( T Number )
{
    stringstream ss;
    ss << Number;
    return ss.str();
}

int main()
{
    cout << "Enter an IP address: ";
    string address;
    cin >> address;
    IpAddress other = address;
    //window
    RenderWindow window(VideoMode(800, 600), "Pong");
    //player 1
    RectangleShape rect(Vector2f(40, 130));
    rect.setPosition(40, 50);
    rect.setFillColor(Color::Blue);
    rect.setOutlineThickness(4);
    rect.setOutlineColor(Color::Black);
    //player 2
    RectangleShape player2(Vector2f(40, 130));
    player2.setPosition(520,50);
    player2.setFillColor(Color(255, 0, 208));
    player2.setOutlineThickness(4);
    player2.setOutlineColor(Color::Black);
    //ball
    CircleShape ball(50, 50);
    ball.setOrigin(ball.getRadius(), ball.getRadius());
    ball.setPosition(400, 300);
    ball.setFillColor(Color(255, 255, 0));
    ball.setOutlineThickness(4);
    ball.setOutlineColor(Color::Black);
    //score
    Uint16 score1;
    Uint16 score2;
    //socket
    short unsigned int port = 54000;
    UdpSocket socket;
    if (socket.bind(port) != Socket::Done)
    {
        cout << "Error\n";
    }
    socket.setBlocking(false);
    //text
    Font font;
    font.loadFromFile("SF Electrotome.ttf");
    Text score;
    score.setFont(font);
    score.setColor(Color::Black);
    score.setString("0  0");
    score.setCharacterSize(16);
    score.setPosition(300, 50);
    //loop
    bool running = true;
    while (running) //game loop
    {
        Event ev;
        while (window.pollEvent(ev)) //event loop
        {
            switch (ev.type)
            {
                case Event::Closed: //quit on click x
                    running = false;
                    break;
                case Event::KeyPressed:
                    if (ev.key.code == Keyboard::Escape) //quit on escape
                    {
                        running = false;
                    }
                    break;
            }
        }
        //get that sweet info
        Packet received;
        socket.receive(received, other, port);
        float player1pos[2];
        float player2pos[2];
        float ballpos[2];
        received >> player1pos[0] >> player1pos[1] >> player2pos[0] >> player2pos[1] >>
        ballpos[0] >> ballpos[1] >> score1 >> score2;
        rect.setPosition(player1pos[0], player1pos[1]);
        player2.setPosition(player2pos[0], player2pos[1]);
        ball.setPosition(ballpos[0], ballpos[1]);
        //scores
        score.setString(NumberToString(score1) + "       " + NumberToString(score2));
        //handle player input
        if (Keyboard::isKeyPressed(Keyboard::Up))
        {
            if (rect.getPosition().y >= 0) //keep in bounds
            {
                Packet p;
                Uint16 direction = 1;
                p << direction;
                socket.send(p, other, port);
            }
        } else if (Keyboard::isKeyPressed(Keyboard::Down)){
            if (player2.getPosition().y + player2.getSize().y <= 600) //keep in bounds
            {
                Packet p;
                Uint16 direction = 2;
                p << direction;
                socket.send(p, other, port);
            }
        }
        //draw everything
        window.clear(Color::White);
        window.draw(rect);
        window.draw(player2);
        window.draw(ball);
        window.draw(score);
        window.display();
    }
    return 0;
}

服务器:

#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <iostream>

using namespace sf;
using namespace std;

template <typename T>
string NumberToString ( T Number )
{
    stringstream ss;
    ss << Number;
    return ss.str();
}

int main()
{
    cout << "Enter an IP address: ";
    string address;
    cin >> address;
    IpAddress other(address);
    if (other == IpAddress::None)
    {
        cout << "Error loading ip";
    }
    srand(time(NULL));
    //window
    RenderWindow window(VideoMode(800, 600), "Pong");
    //player 1
    RectangleShape rect(Vector2f(40, 130));
    rect.setPosition(40, 50);
    rect.setFillColor(Color::Blue);
    rect.setOutlineThickness(4);
    rect.setOutlineColor(Color::Black);
    //player 2
    RectangleShape player2(Vector2f(40, 130));
    player2.setPosition(720, 50);
    player2.setFillColor(Color(255, 0, 208));
    player2.setOutlineThickness(4);
    player2.setOutlineColor(Color::Black);
    //ball
    CircleShape ball(50, 50);
    ball.setOrigin(ball.getRadius(), ball.getRadius());
    ball.setPosition(400, 300);
    ball.setFillColor(Color(255, 255, 0));
    ball.setOutlineThickness(4);
    ball.setOutlineColor(Color::Black);
    float randX = (rand() % 5 + 1);
    float randY = (rand() % 5 + 1);
    Vector2f ballVelocity(randX/15, randY/15);
    //score
    Uint16 score1 = 0;
    Uint16 score2 = 0;
    //text
    Font font;
    font.loadFromFile("SF Electrotome.ttf");
    Text score;
    score.setFont(font);
    score.setColor(Color::Black);
    score.setString("0  0");
    score.setCharacterSize(16);
    score.setPosition(350, 50);
    //network socket
    UdpSocket socket;
    short unsigned int sendPort = 54000;
    if (!(socket.bind(sendPort) == Socket::Done))
    {
        cout << "Error";
    }
    socket.setBlocking(false);
    //loop
    bool running = true;
    while (running) //game loop
    {
        Event ev;
        while (window.pollEvent(ev)) //event loop
        {
            switch (ev.type)
            {
                case Event::Closed: //quit on click x
                    running = false;
                    break;
                case Event::KeyPressed:
                    if (ev.key.code == Keyboard::Escape) //quit on escape
                    {
                        running = false;
                    }
                    break;
            }
        }
        //handle player input
        if (Keyboard::isKeyPressed(Keyboard::Up))
        {
            if (rect.getPosition().y >= 0) //keep in bounds
            {
                rect.move(0, -0.2);
            }
        } else if (Keyboard::isKeyPressed(Keyboard::Down)){
            if (rect.getPosition().y + rect.getSize().y <= 600) //keep in bounds
            {
                rect.move(0, 0.2);
            }
        }
        //handle player 2 input
        Uint16 direction;
        IpAddress sender;
        Packet received;
        if ((socket.receive(received, other, sendPort)) != Socket::Done)
        {
            cout << "Error receiving data";
        }
        received >> direction;
        if (sender == other)
        {
            switch (direction)
            {
                case 1:
                    player2.move(0, -0.2);
                    break;
                case 2:
                    player2.move(0, 0.2);
                    break;
            }
        }
        //handle ball direction changes
        if ((ball.getPosition().y - ball.getRadius() <= 0) || (ball.getPosition().y + ball.getRadius() >= 600)) { //top or bottom
            ballVelocity.y *= -1;
        } else if ((ball.getPosition().x + ball.getRadius() >= 800)) { //right edge
            ballVelocity.x *= -1;
            score1 += 1;
        } else if (ball.getPosition().x - ball.getRadius() <= 0) { //left edge
            ballVelocity.x *= -1;
            score2 += 1;
        }
        ball.move(ballVelocity);
        //handle player/ball collisions
        FloatRect player1Box = rect.getGlobalBounds();
        FloatRect ballBox = ball.getGlobalBounds();
        FloatRect player2Box = player2.getGlobalBounds();
        if (player1Box.intersects(ballBox) || player2Box.intersects(ballBox))
        {
            ballVelocity.x *= -1;
        }
        //set score
        score.setString(NumberToString(score1) + "     " + NumberToString(score2));
        //send everything over
        Packet p;
        p << rect.getPosition().x << rect.getPosition().y << player2.getPosition().x << player2.getPosition().y <<
        ball.getPosition().x << ball.getPosition().y << score1 << score2;
        socket.send(p, other, sendPort);
        //draw everything
        window.clear(Color::White);
        window.draw(rect);
        window.draw(player2);
        window.draw(ball);
        window.draw(score);
        window.display();
    }
    return 0;
}

0 个答案:

没有答案