How to Send messages between server and client using C++ standard library networking TS

Viewed 819

I have tried following the tutorial from boost, however the API is not identical so I have had to guess some parts.

My attempt so far is shown bellow:

#include <iostream>
#include <experimental/internet>
#include <experimental/socket>
#include <thread>
#include <chrono>

using namespace std::experimental;

int main(int argc, char* argv[])
{

    std::thread server = std::thread([]()
    {
        std::cout << "Starting server" << std::endl;

        net::io_context context;
        net::ip::tcp::endpoint endpoint{net::ip::tcp::v4(), 1234};
        net::ip::tcp::acceptor acceptor{context, endpoint};
        acceptor.non_blocking(true);
        std::cout << "opened server on " << endpoint << std::endl;
        std::error_code error;
        net::ip::tcp::socket socket(context);
        while (true)
        {
            socket = acceptor.accept(error); //accept connections
            if (!error) //if connected with a client
            {
                std::cout << "Connected to client!" << std::endl;

                std::this_thread::sleep_for(std::chrono::seconds(2));
                std::string data = "Hello World!";
                net::const_buffer buf(&data, sizeof(data));
                socket.send(buf);
                std::cout << "Sent data!" << std::endl;
                while(true) {}
            }
        }
    });


    std::thread client = std::thread([]()
    {
        net::io_context context;
        net::ip::tcp::socket socket(context);

        net::ip::tcp::endpoint server{net::ip::tcp::v4(), 1234};
        std::error_code error;
        while(true)
        {
            socket.connect(server, error); //attempt to connect
            if (!error) //if connected
            {
                std::cout << "Connected to server!" << std::endl;
                net::mutable_buffer buf;
                while(buf.size() == 0)
                {
                    socket.receive(buf);
                }
                std::cout << "Received data!" << std::endl;
                std::cout << buf.data() << std::endl;
                while(true) {}
            }
        }

    });

    server.join();

    return 0;
}

The sever and client connect, but the message is not received by the client. The output from the program above is:

Starting server
opened server on 0.0.0.0:1234
Connected to server!
Connected to client!
Sent data!

And then it waits forever.

How do I get the socket to correctly receive the data?

1 Answers

This

std::string data = "Hello World!";
net::const_buffer buf(&data, sizeof(data));

is wrong. You want to send content of data string, not its internal bytes. &data gives you a pointer to underlying data of string instance, not its content. If you want to create buffer which represents content of data you can do:

const std::string data = "Hello World!";
net::const_buffer buf = net::buffer(data);

This

net::mutable_buffer buf;
while(buf.size() == 0)
{
    socket.receive(buf);
}

gives you infinite loop because initial size of buf is 0, so receive reads 0 bytes and returns. Then while condition is checked, buf's size is still 0, and the loop goes on.

Before calling receive you need to specify the size of buffer - it indicates how many bytes must be read. You are sending Hello World! so

std::string msg;
msg.resize(12); // prepare space for incoming data
net::mutable_buffer buf = net::buffer(msg);
socket.receive(buf);
std::cout << "I got: " << msg << std::endl;
Related