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

Author Topic: [Solved] sf::Socket::Partial status after TcpSocket::disconnect()  (Read 2569 times)

0 Members and 1 Guest are viewing this topic.

Natulyre

  • Newbie
  • *
  • Posts: 6
    • View Profile
Hello,

I was messing around with TcpSockets after reading about them via Communicating with sockets, but I've ran into an issue. I'm struggling to figure out why it's happening so I'd very much appreciate any help I can get. It's probably a silly mistake.

I've set up a small testing environment for myself split in two solutions, one for the client and one for the server.

If I call TcpSocket::disconnect(), whether it be from the client's side or the server's; it will not result in the other side's socket status on TcpSocket::send([...]) or TcpSocket::receive([...]) to be sf::Socket::Disconnected. It'll always end up as sf::Socket::Partial, until I call disconnect from their side.

I was using this post from Laurent and this post from binary1248 as references points.

These aren't exactly the most recent posts and sf::Socket::Partial status has only been recently introduced with SFML 2.3, but I'd still expect the logic to be valid.

PS: I'm mostly curious in finding out why my issue is happening. I don't plan to do anything specific with this so I wouldn't consider"alternate" solutions (such as using packets or adding a heartbeat ping) to be of much interest or help.

Thanks

Server
#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>

sf::RenderWindow* serverWindow;
sf::TcpListener* listener;
sf::TcpSocket* client;

bool serverIsOpen = false;

void CloseServer()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        client->disconnect();
        listener->close();
        serverIsOpen = false;

        std::cout << "---------------" << std::endl;
}

void OpenServer()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        serverIsOpen = true;

        if (listener->listen(41852) != sf::Socket::Done)
        {
                std::cout << "Listen - Error" << std::endl;
        }
        else
        {
                std::cout << "Listen - OK" << std::endl;
        }

        if (listener->accept(*client) != sf::Socket::Done)
        {
                std::cout << "Accept - Error" << std::endl;
        }
        else
        {
                std::cout << "Accept - Ok" << std::endl;
        }

        std::cout << "---------------" << std::endl;
}

void ReceiveData()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        char data[5];
        std::size_t received;
        sf::Socket::Status status = client->receive(&data, 5, received);

        std::cout << status << "- ";

        switch (status)
        {
        case (sf::Socket::Status::Disconnected) :
                std::cout << "Disconnected" << std::endl;
                break;

        case (sf::Socket::Status::Done) :
                std::cout << "Success" << std::endl;
                break;

        case (sf::Socket::Status::Error) :
        case (sf::Socket::Status::NotReady) :
        case (sf::Socket::Status::Partial) :
        default:
                std::cout << "Error" << std::endl;
                break;
        }

        std::cout << "---------------" << std::endl;
}

void SendData()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        char data[5] = "TEST";

        sf::Socket::Status status = client->send(data, 5);
        std::cout << status << "- ";

        switch (status)
        {
        case (sf::Socket::Status::Disconnected) :
                std::cout << "Disconnected" << std::endl;
                break;

        case (sf::Socket::Status::Done) :
                std::cout << "Success" << std::endl;
                break;

        case (sf::Socket::Status::Error) :
        case (sf::Socket::Status::NotReady) :
        case (sf::Socket::Status::Partial) :
        default:
                std::cout << "Error" << std::endl;
                break;
        }

        std::cout << "---------------" << std::endl;
}

int main()
{
        serverWindow = new sf::RenderWindow(sf::VideoMode(400, 400), "Server Window");

        listener = new sf::TcpListener;
        client = new sf::TcpSocket;

        client->setBlocking(true);

        while (serverWindow != nullptr && serverWindow->isOpen())
        {
                sf::Event event;
                while (serverWindow->pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                        {
                                serverWindow->close();
                        }
                        else if (event.type == sf::Event::KeyPressed)
                        {
                                switch (event.key.code)
                                {
                                case (sf::Keyboard::O) :
                                        if (!serverIsOpen)
                                        {
                                                OpenServer();
                                        }
                                        break;

                                case (sf::Keyboard::C) :
                                        if (serverIsOpen)
                                        {
                                                CloseServer();
                                        }
                                        break;

                                case (sf::Keyboard::R) :
                                        ReceiveData();
                                        break;

                                case (sf::Keyboard::S) :
                                        SendData();
                                        break;

                                default:
                                        break;
                                }
                        }
                }

                serverWindow->clear();
                serverWindow->display();
        }

        return 0;
}
 

Client
#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>

sf::RenderWindow* clientWindow;
sf::TcpSocket* socket;

void Connect()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        sf::Socket::Status status = socket->connect("127.0.0.1", 41852);


        if (status != sf::Socket::Done)
        {
                std::cout << "Client connection attempt failed." << std::endl;
        }
        else
        {
                std::cout << "Client connection attempt succeeded." << std::endl;
        }

        std::cout << "---------------" << std::endl;
}

void Disconnect()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        socket->disconnect();

        std::cout << "---------------" << std::endl;
}

void ReceiveData()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        char data[5];
        std::size_t received;
        sf::Socket::Status status = socket->receive(&data, 5, received);

        std::cout << status << "- ";

        switch (status)
        {
        case (sf::Socket::Status::Disconnected) :
                std::cout << "Disconnected" << std::endl;
                break;

        case (sf::Socket::Status::Done) :
                std::cout << "Success" << std::endl;
                break;

        case (sf::Socket::Status::Error) :
        case (sf::Socket::Status::NotReady) :
        case (sf::Socket::Status::Partial) :
        default:
                std::cout << "Error" << std::endl;
                break;
        }

        std::cout << "---------------" << std::endl;
}

void SendData()
{
        std::cout << "---" << __FUNCTION__ << "---" << std::endl;

        char data[5] = "TEST";

        sf::Socket::Status status = socket->send(data, 5);
        std::cout << status << "- ";

        switch (status)
        {
        case (sf::Socket::Status::Disconnected) :
                std::cout << "Disconnected" << std::endl;
                break;

        case (sf::Socket::Status::Done) :
                std::cout << "Success" << std::endl;
                break;

        case (sf::Socket::Status::Error) :
        case (sf::Socket::Status::NotReady) :
        case (sf::Socket::Status::Partial) :
        default:
                std::cout << "Error" << std::endl;
                break;
        }

        std::cout << "---------------" << std::endl;
}

int main()
{

        clientWindow = new sf::RenderWindow(sf::VideoMode(400, 400), "Client Window");
        socket = new sf::TcpSocket();

        socket->setBlocking(true);

        while (clientWindow != nullptr && clientWindow->isOpen())
        {
                sf::Event event;

                while (clientWindow->pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                        {
                                clientWindow->close();
                        }
                        else if (event.type == sf::Event::KeyPressed)
                        {
                                switch (event.key.code)
                                {
                                case (sf::Keyboard::C) :
                                        Connect();
                                        break;

                                case (sf::Keyboard::D) :
                                        Disconnect();
                                        break;

                                case (sf::Keyboard::R) :
                                        ReceiveData();
                                        break;

                                case (sf::Keyboard::S) :
                                        SendData();
                                        break;

                                default:
                                        break;
                                }
                        }
                }

                clientWindow->clear();
                clientWindow->display();
        }

        return 0;
}
 
« Last Edit: August 05, 2016, 01:41:05 pm by Natulyre »

Natulyre

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: sf::Socket::Partial status after TcpSocket::disconnect()
« Reply #1 on: August 05, 2016, 01:40:51 pm »
I found out the cause of my issue.

When I was testing, I packed up a standalone version of the client-side of my testing environment. Since my project is using dynamically linked libraries I logically had to add SFML's DLL files within my executable's folder.

I meant to try this standalone version on another computer but ended up testing it locally. That's when I noticed, that for the first time, I would receive a sf::Socket::Disconnected state.

I then had an epiphany. I never added any of SFML's DLL files within my projects folder even though I'm using dynamically linked libraries. I never got any missing DLL error so I hadn't even considered it, but Visual Studio's contained within its directory, a bunch of old DLL files from an outdated SFML version. Damn!

I'm now properly receiving a sf::Socket::Disconnected status upon either disconnecting the client or the server and I've learned a great lesson.
« Last Edit: August 05, 2016, 06:14:16 pm by Natulyre »