
Hi Jeremy, --- Jeremy Maitin-Shepard <jbms@cmu.edu> wrote:
Why not use the same names (read and write) for the flags versions, either by giving the flags parameter a default value, or by adding an additional overload?
I'll investigate adding them as overloads, but I think from memory it may cause problems on some compilers due to the existing member template overloads for the custom error handler: void read(void* d, size_t l); template <typename Error_Handler> void read(void* d, size_t l, Error_Handler h);
Perhaps sendto and recvfrom functionality could be provided by additional function overloads using the same names read and write. This would allow better naming consistency.
Using overloads for this would definitely cause problems with the error handler overloads, because both the endpoint and error handler have to be template parameters.
It seems that it might be useful to design the interface in regards to connect such that the user does not have access to methods, such as read and write, when the cannot be used. This could be achieved by providing the user with an object that provides the read/write interface only after connect completes. The socket class itself would not have these functions. I haven't thought this through very much, but it seems like something worth considering.
It might be something that could be accomplished using some non-member functions similar to read/async_read and friends. It only makes sense for a stream socket too, because you can use a datagram socket in an unconnected state, and then connect it and continue to use it. I'll leave this as something to think about after the rest of the interface settles down.
Another related idea is to provide two separate `stream' objects for regular and out-of-band data for TCP. It seems like this could potentially allow for a cleaner interface for sending out-of-band data, but I have also not thought this idea through fully.
Is out-of-band data always (i.e. for all protocols) a stream on a stream_socket? Anyway, it should be easy enough to write a template implementation of the Stream concept (a la buffered_stream) that simply forwards all read/write calls so that they use the appropriate flags for out-of-band data.
What about using platform-specific asynchronous name resolution facilities?
I wanted to get the interface defined first and agreed on. I'll leave platform-specific implementations for a later version.
In what case would some other `service' be used for basic_stream_socket?
I might want to use a custom allocator: typedef basic_stream_socket< stream_socket_service<myallocator> > my_stream_socket; or might want to use a custom demuxing mechanism.
One comment is that the types returned by make_buffer should be known to the user and easy to type, because the sub-buffer methods seem to be primarily useful in the case that the result of make_buffer is stored in a variable rather than passed directly to read, write, and not everyone wants to use templates to avoid having to type types.
The problem with having them return a known type is that the buffer type then has to support an unknown number of segments. IMHO that would impose an unnecessary cost on the case where you just want to send raw memory. If I leave the return type unspecified then: impl_defined_buffer make_buffer(void*, size_t); can return an object that is optimised for the single segment case. Perhaps asio could provide a dynamic buffer class to cater for your use case, which has the same relationship to make_buffer as boost::function has to boost::bind. I.e. buffer b = make_buffer(data, length); Would that be acceptable? Cheers, Chris