
I have reviewed ASIO by browsing some of the documentation and working through the tutorial. What follows are my comments on the library. Regarding the Tutorial: Some of the tutorial material seems too low-level with respect to the facilities available from the C++ Standard Library. Why the use of char arrays, strdup, and strlen? Furthermore, is strdup a standard C++ function? I do not think it is standard C. I would like to see an interface for reading/writing that supports iterators if that makes sense. It would also be nice to be able to read from a socket into an std::string. If that is possible, then it is not obvious from the tutorial. Based on the daytime tutorial, I am concerned that not enough high-level functionality has been added to the library. The daytime examples still have the flavor of using unix sockets. I think that this low-level functionality is critical to flexibility (and perhaps performance), but I would like to be able to quickly construct simple network applications as well. Just for some perspective, here's a tcp daytime server written in the TCL scripting language: -----<snip>----- #!/bin/sh # Standard Trick \ exec tclsh $0 ${1+"$@"} proc serveMe {handle addr port} { puts $handle [clock format [clock seconds]] close $handle } set sk [socket -server serveMe 13] vwait forever -----<snip>----- and here's a tcp datetime client: -----<snip>----- #!/bin/sh # Standard Trick \ exec tclsh $0 ${1+"$@"} if { $argc != 1} { puts stderr "client <host>" exit 1 } set sk [socket [lindex $argv 0] 13] puts -nonewline [read $sk] -----<snip>----- I would like to see an interface at this coarse-grain a level of functionality as well (using the analogous Modern C++ idioms of course). I did not find the Timer 5 example (Using boost threads) to be very compelling. Granted the examples are meant to give a flavor of the library interface, but it may be more compelling to defer multi-threading to the daytime server, perhaps forking a new thread on each connection. This would probably more closely resemble a real use of the facility. I suspect that something more would need to be done to demonstrate synchronization. I am also curious if the library could provide synchronous networking (which asio supports contrary to the library's name) through an iostreams-like interface as well. Demuxer: It appears that any application that uses asio must have one and only one demuxer object floating around. If that is the case, then perhaps it would be wise to model demuxer after std::cout: a global object that is implicitly constructed and destructed and available to any translation unit that includes the relevant header. Demuxer appears to have a more general use than merely i/o. In fact it appears that demuxer could be generally applicable to other asynchronous event handling that might occur in a C++ application (Graphical User Interface come immediately to mind). Existing libraries for GUI's have their own event loop systems. Two issues to consider are: 1) Might future libraries that require asynchrony piggyback off of ASIO's demultiplexing facilitites (For example a C++ GUI library, etc). 2) How can one interleave asio's demultiplexing facilities with other existing event-based libraries. I'm afraid I have not had time to investigate whether and how this can be done in asio currently. But some applications will require mixing asio into some other master event loop. Something of like demuxer::run_one_event() would be a good start. Documentation: The reference documentation seems to be quite good. I do not see documentation for the default class types (such as demuxer) written without reference to the underlying policies involved. It would be very helpful to basic users of the library to have higher-level documentation available in addition to the detailed lower-level documentation. There appear to be some gaps in the documentation on first view (No documentation of the Demuxer_Service concept (modeled by demuxer_service). Code Comments: It was necessary for me to make the following changes to the library in order to prevent warnings and to compile under OS X (Panther/10.3): OS X 10.3 does not define EV_OOBAND. To compile the programs, I had to supply a definition to kqueue_reactor.hpp: #define EV_OOBAND EV_FLAG1 It is not clear to me that this is the proper fix. Furthermore, it was necessary for me to supply some casts in socket_ops.hpp to prevent warnings: recv_bufs[i].iov_len = static_cast<int>(b[i].size); recv_bufs[i].iov_base = static_cast<caddr_t>(b[i].data); ... send_bufs[i].iov_len = static_cast<int>(b[i].size); send_bufs[i].iov_base = static_cast<caddr_t>(b[i].data); Cheers, ron