I want to use an own implementation of std::istream to encapsulate a tcp/ip socket. The main problem I face at the moment is, that in an event driven system I do not want to block the read operation. What I searching for is a standard way to register a callback/event to tell the consuming unit that there are bytes to read. I did not find something in the std::iostream area. Is there a conform solution or have I still to introduce my own interface with function binding?
-
`iostream`s (there is no `std::stream`) operate *on* the stream. They've no idea where they're reading from; that's handled in `std::streambuf`, which you want to customize to abstract other data sources/destinations. – edmz May 13 '15 at 18:00
-
@black I looked into streambuf, but it does not provide the kind of flow control I want for my event driven application. I hoped for some std read/write interface. – Martin Schlott May 13 '15 at 18:03
-
what about creating a thread for the stream or (if you're on unixes) use [`O_NONBLOCK`](http://www.kegel.com/dkftpbench/nonblocking.html). for `streambuf` try [`streambuf::showmanyc`](http://www.cplusplus.com/reference/streambuf/streambuf/showmanyc/) and for `istream` use [`istream::readsome`](http://www.cplusplus.com/reference/istream/basic_istream/readsome/) – programmerjake May 13 '15 at 19:37
2 Answers
std::iostream is blocking, and contains no standard way to detect how many bytes are available. You'll have to introduce your interface.
std::istream::readsome
and will do a non-blocking read from it's internal buffer, but won't check the socket to see if it needs to refill the buffer. It can work for you sometimes, but at other times they will simply insist there is no more data, even when data has been sent to the program. For more information, see this question: C++ std::istream readsome doesn't read anything
ProgrammerJake points out that basic_streambuf::showmanyc
is the interface you're looking for, but is only implemented usefully in some C++ implementations. However, since you're making a replacement buffer anyway, you can simply overload/implement this function however you desire in your buffer class!

- 1
- 1

- 64,318
- 19
- 100
- 158
-
@MartinSchlott: I agree 100%. I _really_ wish there was a non-blocking function to check available bytes :( – Mooing Duck May 13 '15 at 18:12
-
actually there is a way: using `istream::readsome` and `streambuf::showmanyc` (see my other comment on the question) – programmerjake May 13 '15 at 19:43
-
@MooingDuck actually if `streambuf`'s internal buffer is empty it will call `streambuf::showmanyc` which gives the number of `char`s to returned by `underflow`. see [`filebuf::showmanyc`](http://www.cplusplus.com/reference/fstream/basic_filebuf/showmanyc/) – programmerjake May 13 '15 at 20:46
-
1@MooingDuck i meant that your custom `streambuf` for a socket can return the number of characters currently in the kernel buffers. see FIONREAD in [`ioctlsocket`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms738573%28v=vs.85%29.aspx) – programmerjake May 13 '15 at 20:52
-
@programmerjake: Valid point. writing a `showmanyc` is an excellent idea! – Mooing Duck May 13 '15 at 20:59
Have you looked at asio? It provides a tcp::iostream that may do what you need.

- 4,595
- 18
- 24