The client thread works until the call to async_read_some(). The call returns, but I never hit the breakpoint I
set in my handler, nor do I see any output from the handler.

I can't see where you call io_service::run(). If your socket's io_service is not running, noone would process your async. calls.
Please, refer to the asio examples/tutorial to find out how to organize an asyncronous i/o.