2011/6/20 Jaime Fernández <jjja...@gmail.com>: > b) What's the most convenient way to write data in a TCP socket: > 1.- "send" data directly in the read callback > 2.- Create a write watcher > 3.- Create a watcher of both types: READ&WRITE.
It really depends on the nature of the protocol and the data traffic's patterns what will be the most efficient. The most generic answer is this: create both reader and writer watchers for the socket separately, but only activate the read watcher when you need to receive traffic, and only active the write watcher when you have buffered data ready to write to the socket. You can enable and disable them independently with ev_io_start() and ev_io_stop(). e.g. for a simple HTTP server, you might start with only the read watcher enabled. Once you've processed a request and have a response ready to send, you turn on the write watcher to drain the buffered data, then turn it off again when the write buffer is empty. You can also write response data directly from the read watcher that processed the request, and it will probably work 99% of the time for most typical protocols with a serial conversation of reads and writes. However, the write could block because local buffers and the tcp in-flight window are filled, at which point you'll need to buffer the data somewhere per-connection and start up a write watcher to drain it anyways. One way or another, the implementation won't work 100% unless you implement write watcher and a buffer somehow. For an example of trying to be efficient and quick: I recently wrote a proxy server that mostly passes clear data between two connections (other than some initial protocol-specific setup traffic). For that I implemented both read and write watchers for both sides, so 4 watchers per proxied connection. You can think of them as read+write for each socket, but it's more natural pair them the opposite way and think of them as e.g. read_socket1+write_socket2 and read_socket2+write_socket1, for each direction of traffic flow. By default only the read watchers are turned on, and they attempt a non-blocking optimistic write() to the other socket immediately at the end of the read() callback. If the write() fails due to blockage, the data is buffered and the watchers are swapped: the read watcher is disabled, the corresponding write watcher is enabled. The write-watcher, after each invocation where it drains part of the buffer, attempts a non-blocking optimistic read() in order to try to keep the buffer filled. If the buffer drains completely, the traffic flow switches back to watching for read() availability (stop the write watcher, start the read watcher). -- Brandon _______________________________________________ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev