2

is it possible in C++ to do stream like networking?

Something like:

sstream<"www.google.com"> google;
sstream<socket_data> data;
google << "hello";//send hello
google >> data;//read response
if(data.size() > 0)//ok
{
    //manipulate data
}

If yes, how?

I cannot find any information on this topic.

Gizmo
  • 1,990
  • 1
  • 24
  • 50
  • That would be great, but it's definitly not in standart `c++`. Maybe some library supports it. – Haatschii May 28 '14 at 10:26
  • Maybe you want something like the Casablanca library ? https://casablanca.codeplex.com/ – Kiroxas May 28 '14 at 10:26
  • @Kiroxas if it can build on a Raspberry PI with 4GB HDD space then that seems cool :) but still wondering about somethig lightweight. I don't think 4 GB is enough for boost. (I do like boost realllyyy much, but it's not for such mini computers). – Gizmo May 28 '14 at 10:30
  • 2
    You can write your own `streambuf`s and `stream`s, the i/o library's designed to be extensible. – user657267 May 28 '14 at 10:31
  • 1
    Have you considered boost asio? See e.g. [here](http://stackoverflow.com/questions/4275040/create-an-iostream-using-boost-asio-specifying-ip-and-port) for a related question and links to sample code, or e.g. [here for an SSL example](http://stackoverflow.com/questions/3668128/how-to-create-a-boost-ssl-iostream?rq=1) – Tony Delroy May 28 '14 at 10:34
  • You seriously don't want to do this. You want to use a binary protocol defined in octets, with your own library for sending and receiving it. – user207421 Mar 02 '22 at 07:05

1 Answers1

0

I wrote crossplatform network you can find the source here: https://bitbucket.org/ptroen/crossplatformnetwork/src/master/ (it's built on top of boost::asio)

The library generalizes a network protocol quite a bit while getting high performance. For instance this would be a http client (extracted from https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/HTTPClient/main.cc) OSI::Transport::Interface::IClientTransportInitializationParameters init_parameters; init_parameters.ParseServerArgs(&(*argv), argc, 80, 80);

OSI::Transport::HTTP::HTTPClientTransport<SampleProtocol::IncomingPayload<OSI::Transport::Interface::IClientTransportInitializationParameters>, SampleProtocol::OutgoingPayload<OSI::Transport::Interface::IClientTransportInitializationParameters>, SampleProtocol::SampleProtocolClientSession<OSI::Transport::Interface::IClientTransportInitializationParameters>, OSI::Transport::Interface::IClientTransportInitializationParameters> client(init_parameters);
SampleProtocol::IncomingPayload< OSI::Transport::Interface::IClientTransportInitializationParameters> request(init_parameters);
client.RunClient((char*)init_parameters.ipAddress.c_str(), request);

where SampleProtocol is just a class with methods that are called by the templates(see size(),max_size(),ToString() and FromString() but if your in a hurry you could probably just use it as your payload.

With a little work you can wrap it with sstream like interface to achieve that network iostream effect and even pass it to sstream internally if you want extractors.For instance here's a reference on how to derive from std::ostream https://horstmann.com/cpp/iostreams.html (It's used for a different use case but is good reference reading).

Anways to make a network stream library the recipe you need todo is the following:

  1. Make a sstream like class overloading the extraction operators to pass in a string and vice versa.
  2. In the constructor span a new thread(via std::thread) to call the networking code above
  3. Add into the sample protocol(see above) std::atomic or a mutex inside the tostring and from string to pass to the main thread the asyncronous messages back. Basically when you need a mechanism to pass back to the main thread that a payload is ready so your iostream wrapper can pick it up on the main thread. Or you could do blocking(https://www.tutorialspoint.com/what-is-blocking-networks-and-non-blocking-networks-in-computer-architecture) implementation which doesn't require threading but then your networking performance would be worse(because your blocking).

If you want blocking you could just use invoke curl(see here https://linuxize.com/post/curl-command-examples/ if windows install cgywin) on the command line which then a separate thread is not necessary. After curl is invoked take the stream, parse the command line response and pass it back to a string and insert inside your iostream class. The other drawback with this curl approach is you basically have to implement a http client parser of sorts.

Have a nice day :)

ptroen
  • 21
  • 3