SFML community forums

Help => Network => Topic started by: MorleyDev on March 21, 2014, 05:58:20 pm

Title: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: MorleyDev on March 21, 2014, 05:58:20 pm
Hello. So I want to make sure this isn't me doing something stupid or previously mentioned before I open an issue on it.

The following code will run on Linux perfectly, but on Windows (using the nuwen distribution of MinGW) the code compiles but crashes when trying to deserialise the string from the code. Changing it to a sf::String works, so that's a potential workaround. std::wstring will crash too, despite the documentation listing it as supported.

#include <SFML/Network.hpp>
#include <cstdint>
#include <iostream>
#include <stdexcept>

inline std::uint16_t getFreePort()
{
        sf::TcpListener listener;
        listener.listen(sf::TcpListener::AnyPort);
        return listener.getLocalPort();
}
       
int main(int nArgs, char** ppcArgs)
{
        typedef std::string PacketData;
        auto generatePacketData = []() { return PacketData("Hello_World"); };
        auto printPacketData = [](std::ostream& stream, PacketData data) { stream << data; };
       
        const auto port = getFreePort();
        const std::string ip = "127.0.0.1";
       
        std::cout << "Listener listens" << std::endl;
        sf::TcpListener listener;
        if ( listener.listen(port) != sf::Socket::Status::Done )
                throw std::runtime_error("Could not listen on port " + std::to_string(port));
        listener.setBlocking(false);
       
        std::cout << "Client Socket Connects" << std::endl;
        sf::TcpSocket clientSocket;
        if ( clientSocket.connect(sf::IpAddress(ip), port) != sf::Socket::Status::Done )
                throw std::runtime_error("Could not connect to listener on port " + std::to_string(port));
        clientSocket.setBlocking(false);

        std::cout << "Waiting for networking overhead" << std::endl;
        sf::sleep(sf::seconds(1));
       
        std::cout << "Server accepts" << std::endl;
        sf::TcpSocket serverSocket;
        if ( listener.accept(serverSocket) != sf::Socket::Status::Done )
                throw std::runtime_error("Could not accept listener on port " + std::to_string(port));
        serverSocket.setBlocking(false);
       
        const PacketData inData = generatePacketData();
       
        std::cout << "Client sends packet" << std::endl;
        sf::Packet sendPacket;
        sendPacket << inData;
        clientSocket.send(sendPacket);
       
        std::cout << "Server receives packet" << std::endl;
        sf::Packet receivePacket;
        const auto status = serverSocket.receive(receivePacket);
       
        PacketData outData;
        switch(status)
        {
        case sf::Socket::Status::Done:
                std::cout << "Server received packet" << std::endl;
                receivePacket >> outData;
                std::cout << "Server clears packet" << std::endl;
                receivePacket.clear();
                break;

        default:
                throw std::runtime_error("Did not receive packet");
        }
       
        std::cout << "Received packet: ";
        printPacketData(std::cout, outData);
        std::cout << std::endl;
       
        return 0;
}
 

Am I missing something obvious, is std::string/std::wstring not supported with sf::Packet and it crashes or just works because of some overloading nonsense, or is it a known (or unknown) bug in sf::Packet?

Whilst I can use the sf::String solution, a compiler error would of been be nicer than my roundtrip tests of my SFML wrappers crashing (not failing, just straight up crashing) and me having to break out the debugger because of this unintuitive gotcha in SFML's packets.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: antytaon on March 21, 2014, 08:01:54 pm
I just wanted to start new topic about this issue.
I have similar problem. I can send packets consisting of char array and everything works fine. But when I just use:
sf::Packet packet;
packet << "smth";
my programm crashes at second line. No operator overloading works. I am using Windows and cannot test it on linux right now.
Title: AW: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: eXpl0it3r on March 21, 2014, 09:23:39 pm
Haven't investigated (yet), but it sounds like some encoding issue, thus it might be useful to provide the encoding of your source files and how the compiler treats "string" constances. ;)
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: antytaon on March 21, 2014, 10:58:51 pm
I got problem with:
sf::IpAddress address = client->getRemoteAddress();
std::cout << address;
std::string ipA = address.toString(); // this line crashes
The last line crashes too, can it be linked to previous situation?
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: Laurent on March 22, 2014, 07:54:53 am
It looks like a bad mix of C++ runtimes. What is your compiler?
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: antytaon on March 22, 2014, 09:11:01 am
I use Microsoft Visual Studio 2013 and I build app with x64 configuration.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: eXpl0it3r on March 22, 2014, 09:14:10 am
And you've built SFML manually, right? There are no VS 2013 packages.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: antytaon on March 22, 2014, 09:36:19 am
Aww forgot about it. I will do this now and tell you about results :)
EDIT: Big thanks, building SFML from source code brought working strings in VS 2013  :D
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: MorleyDev on March 22, 2014, 02:28:35 pm
I'm using the latest version of the nuwen mingw distribution (http://nuwen.net/mingw.html). I rebuilt SFML again to make sure I hadn't accidentally updated the compiler and not SFML, but the crash still happens.

I found a work around in passing an std::string to an sf::String and serialising the sf::String on send, and deserialising to another sf::String and then extracting the std::string from the sf::String via toAnsiString on receive.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: binary1248 on March 22, 2014, 02:59:38 pm
You could try running:
#include <iostream>
#include <string>
#include <SFML/Network.hpp>

int main() {
        std::cout << "sf::Uint32: " << sizeof(sf::Uint32) << "\n";
        std::cout << "std::string::value_type: " << sizeof(std::string::value_type) << "\n";
        std::cout << "std::wstring::value_type: " << sizeof(std::wstring::value_type) << "\n";
}
to rule out any exotic data type sizes.

I don't know if it would make sense making the string serialization/deserialization more uniform in that it packs the characters into sf::Uint32s regardless of what kind of string it receives. It would make it less of an adventure when trying to communicate between hosts which for some reason might not have the same idea of how big a certain type should be. There will be a bit more overhead, yes. However, considering the bulk of the data flow in a typical application shouldn't consist of strings being transferred, the impact will be barely noticeable.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: MorleyDev on March 22, 2014, 04:00:36 pm
sizeof(sf::Uint32) = 4
sizeof(std::string::value_type) = 1
sizeof(std::wstring::value_type) = 2
Seems like pretty standard sizes to me.

As an aside, you say strings won't compose much of networking, but I would like to note that client/server communication via JSON isn't that uncommon in games.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: binary1248 on March 22, 2014, 07:37:05 pm
Let's just say... if you wanted to minimize delay and maximize throughput you wouldn't be using something like JSON as your primary communication medium...
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: Nexus on March 23, 2014, 12:36:02 pm
...you would use XML ;D

(actually, it's amazing how a format of this verbosity could become so popular)
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: MorleyDev on March 23, 2014, 04:16:57 pm
My point was more that for your average modern 2-4 player game, JSON would be "sufficient enough" for usage.

But anyway getting distracted...has anybody actually tried this code on their setup? :S Because if it's not just happening for me, the only reason I can think for it failing is some DLL/EXE boundary shenanigans.

But I can pass it to an sf::String constructor just fine, and get the value from toAnsiString, and aren't they both crossing the System DLL boundary?
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: binary1248 on March 23, 2014, 05:42:07 pm
Did you try running debug and checking whether the stuff going on inside operator>> and operator<< is sane? If the standard library is called with bogus parameters it can't really help but crash.
Title: Re: [Bug?] std::string on Packets crashes on Windows but not Linux (mingw/g++)
Post by: eXpl0it3r on March 23, 2014, 06:24:56 pm
So I got around to test it. Works fine on my system (Windows 8.1) with the compiler from MinGW Builds 4.8.1 POSIX 32bit SJLJ.

However keep in mind that I've linked everything statically. From runtime lib to the SFML libs.