From da0cf5f68a41032017065c9d92b3c18f37a4c43e Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Wed, 14 Jun 2006 22:26:36 +0000 Subject: [PATCH] Initial asio checkin. [SVN r34306] --- .gitattributes | 96 + example/allocation/Jamfile | 25 + example/allocation/server.cpp | 229 +++ example/buffers/Jamfile | 25 + example/buffers/reference_counted.cpp | 118 ++ example/chat/Jamfile | 38 + example/chat/chat_client.cpp | 181 ++ example/chat/chat_message.hpp | 83 + example/chat/chat_server.cpp | 237 +++ example/echo/Jamfile | 55 + example/echo/async_tcp_echo_server.cpp | 126 ++ example/echo/async_udp_echo_server.cpp | 86 + example/echo/blocking_tcp_echo_client.cpp | 53 + example/echo/blocking_tcp_echo_server.cpp | 79 + example/echo/blocking_udp_echo_client.cpp | 53 + example/echo/blocking_udp_echo_server.cpp | 47 + example/http/server/Jamfile | 34 + example/http/server/connection.cpp | 82 + example/http/server/connection.hpp | 72 + example/http/server/connection_manager.cpp | 28 + example/http/server/connection_manager.hpp | 34 + example/http/server/header.hpp | 18 + example/http/server/mime_types.cpp | 36 + example/http/server/mime_types.hpp | 17 + example/http/server/posix_main.cpp | 67 + example/http/server/reply.cpp | 246 +++ example/http/server/reply.hpp | 54 + example/http/server/request.hpp | 24 + example/http/server/request_handler.cpp | 107 + example/http/server/request_handler.hpp | 36 + example/http/server/request_parser.cpp | 316 +++ example/http/server/request_parser.hpp | 86 + example/http/server/server.cpp | 68 + example/http/server/server.hpp | 56 + example/http/server/win_main.cpp | 64 + example/iostreams/Jamfile | 36 + example/iostreams/daytime_client.cpp | 28 + example/iostreams/daytime_server.cpp | 37 + example/multicast/Jamfile | 36 + example/multicast/receiver.cpp | 82 + example/multicast/sender.cpp | 93 + example/serialization/Jamfile | 38 + example/serialization/client.cpp | 126 ++ example/serialization/connection.hpp | 174 ++ example/serialization/server.cpp | 120 ++ example/serialization/stock.hpp | 40 + example/services/Jamfile | 26 + example/services/basic_logger.hpp | 73 + example/services/daytime_client.cpp | 85 + example/services/logger.hpp | 14 + example/services/logger_service.hpp | 133 ++ example/services/stream_socket_service.hpp | 314 +++ example/ssl/Jamfile | 40 + example/ssl/README | 1 + example/ssl/ca.pem | 31 + example/ssl/client.cpp | 135 ++ example/ssl/dh512.pem | 12 + example/ssl/server.cpp | 152 ++ example/ssl/server.pem | 44 + example/timeouts/Jamfile | 45 + example/timeouts/accept_timeout.cpp | 67 + example/timeouts/connect_timeout.cpp | 78 + example/timeouts/datagram_receive_timeout.cpp | 70 + example/timeouts/stream_receive_timeout.cpp | 94 + example/tutorial/Jamfile | 38 + example/tutorial/daytime1/client.cpp | 56 + example/tutorial/daytime2/server.cpp | 40 + example/tutorial/daytime3/server.cpp | 106 + example/tutorial/daytime4/client.cpp | 42 + example/tutorial/daytime5/server.cpp | 47 + example/tutorial/daytime6/server.cpp | 78 + example/tutorial/daytime7/server.cpp | 147 ++ example/tutorial/timer1/timer.cpp | 15 + example/tutorial/timer2/timer.cpp | 20 + example/tutorial/timer3/timer.cpp | 34 + example/tutorial/timer4/timer.cpp | 45 + example/tutorial/timer5/timer.cpp | 65 + include/boost/asio.hpp | 71 + include/boost/asio/basic_datagram_socket.hpp | 802 ++++++++ include/boost/asio/basic_deadline_timer.hpp | 311 +++ include/boost/asio/basic_io_object.hpp | 77 + include/boost/asio/basic_resolver.hpp | 254 +++ include/boost/asio/basic_socket.hpp | 884 ++++++++ include/boost/asio/basic_socket_acceptor.hpp | 816 ++++++++ include/boost/asio/basic_socket_iostream.hpp | 156 ++ include/boost/asio/basic_socketbuf.hpp | 260 +++ include/boost/asio/basic_strand.hpp | 144 ++ include/boost/asio/basic_stream_socket.hpp | 818 ++++++++ include/boost/asio/basic_streambuf.hpp | 421 ++++ include/boost/asio/buffer.hpp | 641 ++++++ include/boost/asio/buffered_read_stream.hpp | 409 ++++ .../boost/asio/buffered_read_stream_fwd.hpp | 31 + include/boost/asio/buffered_stream.hpp | 251 +++ include/boost/asio/buffered_stream_fwd.hpp | 31 + include/boost/asio/buffered_write_stream.hpp | 364 ++++ .../boost/asio/buffered_write_stream_fwd.hpp | 31 + include/boost/asio/completion_condition.hpp | 103 + .../boost/asio/datagram_socket_service.hpp | 290 +++ include/boost/asio/deadline_timer.hpp | 39 + include/boost/asio/deadline_timer_service.hpp | 154 ++ include/boost/asio/detail/bind_handler.hpp | 288 +++ .../boost/asio/detail/buffer_resize_guard.hpp | 72 + .../asio/detail/buffered_stream_storage.hpp | 129 ++ include/boost/asio/detail/call_stack.hpp | 92 + .../asio/detail/const_buffers_iterator.hpp | 152 ++ .../boost/asio/detail/consuming_buffers.hpp | 198 ++ include/boost/asio/detail/epoll_reactor.hpp | 570 +++++ .../boost/asio/detail/epoll_reactor_fwd.hpp | 49 + include/boost/asio/detail/event.hpp | 52 + include/boost/asio/detail/fd_set_adapter.hpp | 69 + .../asio/detail/handler_alloc_helpers.hpp | 258 +++ include/boost/asio/detail/hash_map.hpp | 197 ++ include/boost/asio/detail/io_control.hpp | 141 ++ include/boost/asio/detail/kqueue_reactor.hpp | 566 +++++ .../boost/asio/detail/kqueue_reactor_fwd.hpp | 43 + include/boost/asio/detail/mutex.hpp | 52 + include/boost/asio/detail/noncopyable.hpp | 57 + include/boost/asio/detail/null_event.hpp | 70 + include/boost/asio/detail/null_mutex.hpp | 68 + .../boost/asio/detail/null_signal_blocker.hpp | 65 + include/boost/asio/detail/null_thread.hpp | 69 + include/boost/asio/detail/null_tss_ptr.hpp | 72 + .../boost/asio/detail/old_win_sdk_compat.hpp | 314 +++ .../asio/detail/pipe_select_interrupter.hpp | 106 + include/boost/asio/detail/pop_options.hpp | 88 + include/boost/asio/detail/posix_event.hpp | 109 + include/boost/asio/detail/posix_mutex.hpp | 96 + .../asio/detail/posix_signal_blocker.hpp | 91 + include/boost/asio/detail/posix_thread.hpp | 127 ++ include/boost/asio/detail/posix_tss_ptr.hpp | 86 + include/boost/asio/detail/push_options.hpp | 106 + .../reactive_deadline_timer_service.hpp | 179 ++ .../asio/detail/reactive_socket_service.hpp | 1544 ++++++++++++++ .../boost/asio/detail/reactor_op_queue.hpp | 381 ++++ .../boost/asio/detail/reactor_timer_queue.hpp | 340 +++ .../boost/asio/detail/resolver_service.hpp | 363 ++++ include/boost/asio/detail/scoped_lock.hpp | 81 + .../boost/asio/detail/select_interrupter.hpp | 43 + include/boost/asio/detail/select_reactor.hpp | 408 ++++ .../boost/asio/detail/select_reactor_fwd.hpp | 33 + .../boost/asio/detail/service_registry.hpp | 165 ++ include/boost/asio/detail/signal_blocker.hpp | 52 + include/boost/asio/detail/signal_init.hpp | 53 + include/boost/asio/detail/socket_holder.hpp | 93 + include/boost/asio/detail/socket_ops.hpp | 1514 ++++++++++++++ include/boost/asio/detail/socket_option.hpp | 325 +++ .../asio/detail/socket_select_interrupter.hpp | 179 ++ include/boost/asio/detail/socket_types.hpp | 162 ++ include/boost/asio/detail/strand_service.hpp | 427 ++++ include/boost/asio/detail/task_io_service.hpp | 459 +++++ .../boost/asio/detail/task_io_service_fwd.hpp | 33 + include/boost/asio/detail/thread.hpp | 52 + include/boost/asio/detail/tss_ptr.hpp | 67 + include/boost/asio/detail/win_event.hpp | 90 + .../boost/asio/detail/win_iocp_io_service.hpp | 334 +++ .../asio/detail/win_iocp_io_service_fwd.hpp | 48 + .../boost/asio/detail/win_iocp_operation.hpp | 83 + .../asio/detail/win_iocp_socket_service.hpp | 1825 +++++++++++++++++ .../detail/win_local_free_on_block_exit.hpp | 61 + include/boost/asio/detail/win_mutex.hpp | 144 ++ .../boost/asio/detail/win_signal_blocker.hpp | 69 + include/boost/asio/detail/win_thread.hpp | 123 ++ include/boost/asio/detail/win_tss_ptr.hpp | 87 + include/boost/asio/detail/winsock_init.hpp | 118 ++ include/boost/asio/detail/wrapped_handler.hpp | 140 ++ include/boost/asio/error.hpp | 388 ++++ include/boost/asio/error_handler.hpp | 122 ++ include/boost/asio/handler_alloc_hook.hpp | 90 + include/boost/asio/impl/io_service.ipp | 132 ++ include/boost/asio/impl/read.ipp | 153 ++ include/boost/asio/impl/read_until.ipp | 395 ++++ include/boost/asio/impl/write.ipp | 152 ++ include/boost/asio/io_service.hpp | 386 ++++ include/boost/asio/ip/address.hpp | 286 +++ include/boost/asio/ip/address_v4.hpp | 263 +++ include/boost/asio/ip/address_v6.hpp | 330 +++ include/boost/asio/ip/basic_endpoint.hpp | 357 ++++ .../boost/asio/ip/basic_resolver_entry.hpp | 100 + .../boost/asio/ip/basic_resolver_iterator.hpp | 153 ++ .../boost/asio/ip/basic_resolver_query.hpp | 154 ++ .../boost/asio/ip/detail/socket_option.hpp | 408 ++++ include/boost/asio/ip/host_name.hpp | 62 + include/boost/asio/ip/multicast.hpp | 183 ++ include/boost/asio/ip/resolver_query_base.hpp | 109 + include/boost/asio/ip/tcp.hpp | 148 ++ include/boost/asio/ip/udp.hpp | 106 + include/boost/asio/is_read_buffered.hpp | 64 + include/boost/asio/is_write_buffered.hpp | 64 + include/boost/asio/placeholders.hpp | 82 + include/boost/asio/read.hpp | 326 +++ include/boost/asio/read_until.hpp | 343 ++++ include/boost/asio/resolver_service.hpp | 128 ++ .../boost/asio/socket_acceptor_service.hpp | 214 ++ include/boost/asio/socket_base.hpp | 477 +++++ include/boost/asio/ssl.hpp | 26 + include/boost/asio/ssl/basic_context.hpp | 421 ++++ include/boost/asio/ssl/context.hpp | 37 + include/boost/asio/ssl/context_base.hpp | 156 ++ include/boost/asio/ssl/context_service.hpp | 165 ++ .../ssl/detail/openssl_context_service.hpp | 303 +++ .../boost/asio/ssl/detail/openssl_init.hpp | 124 ++ .../asio/ssl/detail/openssl_operation.hpp | 428 ++++ .../ssl/detail/openssl_stream_service.hpp | 444 ++++ .../boost/asio/ssl/detail/openssl_types.hpp | 26 + include/boost/asio/ssl/stream.hpp | 511 +++++ include/boost/asio/ssl/stream_base.hpp | 62 + include/boost/asio/ssl/stream_service.hpp | 175 ++ include/boost/asio/strand.hpp | 33 + include/boost/asio/strand_service.hpp | 90 + include/boost/asio/stream_socket_service.hpp | 251 +++ include/boost/asio/streambuf.hpp | 33 + include/boost/asio/system_exception.hpp | 199 ++ include/boost/asio/time_traits.hpp | 79 + include/boost/asio/write.hpp | 319 +++ index.html | 9 + test/Jamfile | 69 + test/Jamfile.v2 | 116 ++ test/basic_datagram_socket_test.cpp | 25 + test/basic_deadline_timer_test.cpp | 25 + test/basic_resolver_test.cpp | 25 + test/basic_socket_acceptor_test.cpp | 25 + test/basic_strand_test.cpp | 25 + test/basic_stream_socket_test.cpp | 25 + test/buffer_test.cpp | 147 ++ test/buffered_read_stream_test.cpp | 221 ++ test/buffered_stream_test.cpp | 236 +++ test/buffered_write_stream_test.cpp | 236 +++ test/completion_condition_test.cpp | 25 + test/datagram_socket_service_test.cpp | 25 + test/deadline_timer_service_test.cpp | 25 + test/deadline_timer_test.cpp | 186 ++ test/error_handler_test.cpp | 67 + test/error_test.cpp | 92 + test/io_service_test.cpp | 237 +++ test/ip/address_test.cpp | 25 + test/ip/address_v4_test.cpp | 25 + test/ip/address_v6_test.cpp | 25 + test/ip/basic_endpoint_test.cpp | 25 + test/ip/basic_resolver_entry_test.cpp | 25 + test/ip/basic_resolver_iterator_test.cpp | 25 + test/ip/basic_resolver_query_test.cpp | 25 + test/ip/host_name_test.cpp | 54 + test/ip/multicast_test.cpp | 25 + test/ip/resolver_query_base_test.cpp | 25 + test/ip/tcp_test.cpp | 272 +++ test/ip/udp_test.cpp | 280 +++ test/is_read_buffered_test.cpp | 126 ++ test/is_write_buffered_test.cpp | 126 ++ test/placeholders_test.cpp | 25 + test/read_test.cpp | 631 ++++++ test/resolver_service_test.cpp | 25 + test/socket_acceptor_service_test.cpp | 25 + test/socket_base_test.cpp | 25 + test/ssl/Jamfile | 37 + test/ssl/Jamfile.v2 | 51 + test/ssl/basic_context_test.cpp | 25 + test/ssl/context_base_test.cpp | 25 + test/ssl/context_service_test.cpp | 25 + test/ssl/context_test.cpp | 25 + test/ssl/stream_base_test.cpp | 25 + test/ssl/stream_service_test.cpp | 25 + test/ssl/stream_test.cpp | 25 + test/strand_service_test.cpp | 25 + test/strand_test.cpp | 166 ++ test/stream_socket_service_test.cpp | 25 + test/time_traits_test.cpp | 25 + test/unit_test.hpp | 40 + test/write_test.cpp | 586 ++++++ 268 files changed, 42660 insertions(+) create mode 100644 .gitattributes create mode 100644 example/allocation/Jamfile create mode 100644 example/allocation/server.cpp create mode 100644 example/buffers/Jamfile create mode 100644 example/buffers/reference_counted.cpp create mode 100644 example/chat/Jamfile create mode 100644 example/chat/chat_client.cpp create mode 100644 example/chat/chat_message.hpp create mode 100644 example/chat/chat_server.cpp create mode 100644 example/echo/Jamfile create mode 100644 example/echo/async_tcp_echo_server.cpp create mode 100644 example/echo/async_udp_echo_server.cpp create mode 100644 example/echo/blocking_tcp_echo_client.cpp create mode 100644 example/echo/blocking_tcp_echo_server.cpp create mode 100644 example/echo/blocking_udp_echo_client.cpp create mode 100644 example/echo/blocking_udp_echo_server.cpp create mode 100644 example/http/server/Jamfile create mode 100644 example/http/server/connection.cpp create mode 100644 example/http/server/connection.hpp create mode 100644 example/http/server/connection_manager.cpp create mode 100644 example/http/server/connection_manager.hpp create mode 100644 example/http/server/header.hpp create mode 100644 example/http/server/mime_types.cpp create mode 100644 example/http/server/mime_types.hpp create mode 100644 example/http/server/posix_main.cpp create mode 100644 example/http/server/reply.cpp create mode 100644 example/http/server/reply.hpp create mode 100644 example/http/server/request.hpp create mode 100644 example/http/server/request_handler.cpp create mode 100644 example/http/server/request_handler.hpp create mode 100644 example/http/server/request_parser.cpp create mode 100644 example/http/server/request_parser.hpp create mode 100644 example/http/server/server.cpp create mode 100644 example/http/server/server.hpp create mode 100644 example/http/server/win_main.cpp create mode 100644 example/iostreams/Jamfile create mode 100644 example/iostreams/daytime_client.cpp create mode 100644 example/iostreams/daytime_server.cpp create mode 100644 example/multicast/Jamfile create mode 100644 example/multicast/receiver.cpp create mode 100644 example/multicast/sender.cpp create mode 100644 example/serialization/Jamfile create mode 100644 example/serialization/client.cpp create mode 100644 example/serialization/connection.hpp create mode 100644 example/serialization/server.cpp create mode 100644 example/serialization/stock.hpp create mode 100644 example/services/Jamfile create mode 100644 example/services/basic_logger.hpp create mode 100644 example/services/daytime_client.cpp create mode 100644 example/services/logger.hpp create mode 100644 example/services/logger_service.hpp create mode 100644 example/services/stream_socket_service.hpp create mode 100644 example/ssl/Jamfile create mode 100644 example/ssl/README create mode 100644 example/ssl/ca.pem create mode 100644 example/ssl/client.cpp create mode 100644 example/ssl/dh512.pem create mode 100644 example/ssl/server.cpp create mode 100644 example/ssl/server.pem create mode 100644 example/timeouts/Jamfile create mode 100644 example/timeouts/accept_timeout.cpp create mode 100644 example/timeouts/connect_timeout.cpp create mode 100644 example/timeouts/datagram_receive_timeout.cpp create mode 100644 example/timeouts/stream_receive_timeout.cpp create mode 100644 example/tutorial/Jamfile create mode 100644 example/tutorial/daytime1/client.cpp create mode 100644 example/tutorial/daytime2/server.cpp create mode 100644 example/tutorial/daytime3/server.cpp create mode 100644 example/tutorial/daytime4/client.cpp create mode 100644 example/tutorial/daytime5/server.cpp create mode 100644 example/tutorial/daytime6/server.cpp create mode 100644 example/tutorial/daytime7/server.cpp create mode 100644 example/tutorial/timer1/timer.cpp create mode 100644 example/tutorial/timer2/timer.cpp create mode 100644 example/tutorial/timer3/timer.cpp create mode 100644 example/tutorial/timer4/timer.cpp create mode 100644 example/tutorial/timer5/timer.cpp create mode 100644 include/boost/asio.hpp create mode 100644 include/boost/asio/basic_datagram_socket.hpp create mode 100644 include/boost/asio/basic_deadline_timer.hpp create mode 100644 include/boost/asio/basic_io_object.hpp create mode 100644 include/boost/asio/basic_resolver.hpp create mode 100644 include/boost/asio/basic_socket.hpp create mode 100644 include/boost/asio/basic_socket_acceptor.hpp create mode 100644 include/boost/asio/basic_socket_iostream.hpp create mode 100644 include/boost/asio/basic_socketbuf.hpp create mode 100644 include/boost/asio/basic_strand.hpp create mode 100644 include/boost/asio/basic_stream_socket.hpp create mode 100644 include/boost/asio/basic_streambuf.hpp create mode 100644 include/boost/asio/buffer.hpp create mode 100644 include/boost/asio/buffered_read_stream.hpp create mode 100644 include/boost/asio/buffered_read_stream_fwd.hpp create mode 100644 include/boost/asio/buffered_stream.hpp create mode 100644 include/boost/asio/buffered_stream_fwd.hpp create mode 100644 include/boost/asio/buffered_write_stream.hpp create mode 100644 include/boost/asio/buffered_write_stream_fwd.hpp create mode 100644 include/boost/asio/completion_condition.hpp create mode 100644 include/boost/asio/datagram_socket_service.hpp create mode 100644 include/boost/asio/deadline_timer.hpp create mode 100644 include/boost/asio/deadline_timer_service.hpp create mode 100644 include/boost/asio/detail/bind_handler.hpp create mode 100644 include/boost/asio/detail/buffer_resize_guard.hpp create mode 100644 include/boost/asio/detail/buffered_stream_storage.hpp create mode 100644 include/boost/asio/detail/call_stack.hpp create mode 100644 include/boost/asio/detail/const_buffers_iterator.hpp create mode 100644 include/boost/asio/detail/consuming_buffers.hpp create mode 100644 include/boost/asio/detail/epoll_reactor.hpp create mode 100644 include/boost/asio/detail/epoll_reactor_fwd.hpp create mode 100644 include/boost/asio/detail/event.hpp create mode 100644 include/boost/asio/detail/fd_set_adapter.hpp create mode 100644 include/boost/asio/detail/handler_alloc_helpers.hpp create mode 100644 include/boost/asio/detail/hash_map.hpp create mode 100644 include/boost/asio/detail/io_control.hpp create mode 100644 include/boost/asio/detail/kqueue_reactor.hpp create mode 100644 include/boost/asio/detail/kqueue_reactor_fwd.hpp create mode 100644 include/boost/asio/detail/mutex.hpp create mode 100644 include/boost/asio/detail/noncopyable.hpp create mode 100644 include/boost/asio/detail/null_event.hpp create mode 100644 include/boost/asio/detail/null_mutex.hpp create mode 100644 include/boost/asio/detail/null_signal_blocker.hpp create mode 100644 include/boost/asio/detail/null_thread.hpp create mode 100644 include/boost/asio/detail/null_tss_ptr.hpp create mode 100644 include/boost/asio/detail/old_win_sdk_compat.hpp create mode 100644 include/boost/asio/detail/pipe_select_interrupter.hpp create mode 100644 include/boost/asio/detail/pop_options.hpp create mode 100644 include/boost/asio/detail/posix_event.hpp create mode 100644 include/boost/asio/detail/posix_mutex.hpp create mode 100644 include/boost/asio/detail/posix_signal_blocker.hpp create mode 100644 include/boost/asio/detail/posix_thread.hpp create mode 100644 include/boost/asio/detail/posix_tss_ptr.hpp create mode 100644 include/boost/asio/detail/push_options.hpp create mode 100644 include/boost/asio/detail/reactive_deadline_timer_service.hpp create mode 100644 include/boost/asio/detail/reactive_socket_service.hpp create mode 100644 include/boost/asio/detail/reactor_op_queue.hpp create mode 100644 include/boost/asio/detail/reactor_timer_queue.hpp create mode 100644 include/boost/asio/detail/resolver_service.hpp create mode 100644 include/boost/asio/detail/scoped_lock.hpp create mode 100644 include/boost/asio/detail/select_interrupter.hpp create mode 100644 include/boost/asio/detail/select_reactor.hpp create mode 100644 include/boost/asio/detail/select_reactor_fwd.hpp create mode 100644 include/boost/asio/detail/service_registry.hpp create mode 100644 include/boost/asio/detail/signal_blocker.hpp create mode 100644 include/boost/asio/detail/signal_init.hpp create mode 100644 include/boost/asio/detail/socket_holder.hpp create mode 100644 include/boost/asio/detail/socket_ops.hpp create mode 100644 include/boost/asio/detail/socket_option.hpp create mode 100644 include/boost/asio/detail/socket_select_interrupter.hpp create mode 100644 include/boost/asio/detail/socket_types.hpp create mode 100644 include/boost/asio/detail/strand_service.hpp create mode 100644 include/boost/asio/detail/task_io_service.hpp create mode 100644 include/boost/asio/detail/task_io_service_fwd.hpp create mode 100644 include/boost/asio/detail/thread.hpp create mode 100644 include/boost/asio/detail/tss_ptr.hpp create mode 100644 include/boost/asio/detail/win_event.hpp create mode 100644 include/boost/asio/detail/win_iocp_io_service.hpp create mode 100644 include/boost/asio/detail/win_iocp_io_service_fwd.hpp create mode 100644 include/boost/asio/detail/win_iocp_operation.hpp create mode 100644 include/boost/asio/detail/win_iocp_socket_service.hpp create mode 100644 include/boost/asio/detail/win_local_free_on_block_exit.hpp create mode 100644 include/boost/asio/detail/win_mutex.hpp create mode 100644 include/boost/asio/detail/win_signal_blocker.hpp create mode 100644 include/boost/asio/detail/win_thread.hpp create mode 100644 include/boost/asio/detail/win_tss_ptr.hpp create mode 100644 include/boost/asio/detail/winsock_init.hpp create mode 100644 include/boost/asio/detail/wrapped_handler.hpp create mode 100644 include/boost/asio/error.hpp create mode 100644 include/boost/asio/error_handler.hpp create mode 100644 include/boost/asio/handler_alloc_hook.hpp create mode 100644 include/boost/asio/impl/io_service.ipp create mode 100644 include/boost/asio/impl/read.ipp create mode 100644 include/boost/asio/impl/read_until.ipp create mode 100644 include/boost/asio/impl/write.ipp create mode 100644 include/boost/asio/io_service.hpp create mode 100644 include/boost/asio/ip/address.hpp create mode 100644 include/boost/asio/ip/address_v4.hpp create mode 100644 include/boost/asio/ip/address_v6.hpp create mode 100644 include/boost/asio/ip/basic_endpoint.hpp create mode 100644 include/boost/asio/ip/basic_resolver_entry.hpp create mode 100644 include/boost/asio/ip/basic_resolver_iterator.hpp create mode 100644 include/boost/asio/ip/basic_resolver_query.hpp create mode 100644 include/boost/asio/ip/detail/socket_option.hpp create mode 100644 include/boost/asio/ip/host_name.hpp create mode 100644 include/boost/asio/ip/multicast.hpp create mode 100644 include/boost/asio/ip/resolver_query_base.hpp create mode 100644 include/boost/asio/ip/tcp.hpp create mode 100644 include/boost/asio/ip/udp.hpp create mode 100644 include/boost/asio/is_read_buffered.hpp create mode 100644 include/boost/asio/is_write_buffered.hpp create mode 100644 include/boost/asio/placeholders.hpp create mode 100644 include/boost/asio/read.hpp create mode 100644 include/boost/asio/read_until.hpp create mode 100644 include/boost/asio/resolver_service.hpp create mode 100644 include/boost/asio/socket_acceptor_service.hpp create mode 100644 include/boost/asio/socket_base.hpp create mode 100644 include/boost/asio/ssl.hpp create mode 100644 include/boost/asio/ssl/basic_context.hpp create mode 100644 include/boost/asio/ssl/context.hpp create mode 100644 include/boost/asio/ssl/context_base.hpp create mode 100644 include/boost/asio/ssl/context_service.hpp create mode 100644 include/boost/asio/ssl/detail/openssl_context_service.hpp create mode 100644 include/boost/asio/ssl/detail/openssl_init.hpp create mode 100644 include/boost/asio/ssl/detail/openssl_operation.hpp create mode 100644 include/boost/asio/ssl/detail/openssl_stream_service.hpp create mode 100644 include/boost/asio/ssl/detail/openssl_types.hpp create mode 100644 include/boost/asio/ssl/stream.hpp create mode 100644 include/boost/asio/ssl/stream_base.hpp create mode 100644 include/boost/asio/ssl/stream_service.hpp create mode 100644 include/boost/asio/strand.hpp create mode 100644 include/boost/asio/strand_service.hpp create mode 100644 include/boost/asio/stream_socket_service.hpp create mode 100644 include/boost/asio/streambuf.hpp create mode 100644 include/boost/asio/system_exception.hpp create mode 100644 include/boost/asio/time_traits.hpp create mode 100644 include/boost/asio/write.hpp create mode 100644 index.html create mode 100644 test/Jamfile create mode 100644 test/Jamfile.v2 create mode 100644 test/basic_datagram_socket_test.cpp create mode 100644 test/basic_deadline_timer_test.cpp create mode 100644 test/basic_resolver_test.cpp create mode 100644 test/basic_socket_acceptor_test.cpp create mode 100644 test/basic_strand_test.cpp create mode 100644 test/basic_stream_socket_test.cpp create mode 100644 test/buffer_test.cpp create mode 100644 test/buffered_read_stream_test.cpp create mode 100644 test/buffered_stream_test.cpp create mode 100644 test/buffered_write_stream_test.cpp create mode 100644 test/completion_condition_test.cpp create mode 100644 test/datagram_socket_service_test.cpp create mode 100644 test/deadline_timer_service_test.cpp create mode 100644 test/deadline_timer_test.cpp create mode 100644 test/error_handler_test.cpp create mode 100644 test/error_test.cpp create mode 100644 test/io_service_test.cpp create mode 100644 test/ip/address_test.cpp create mode 100644 test/ip/address_v4_test.cpp create mode 100644 test/ip/address_v6_test.cpp create mode 100644 test/ip/basic_endpoint_test.cpp create mode 100644 test/ip/basic_resolver_entry_test.cpp create mode 100644 test/ip/basic_resolver_iterator_test.cpp create mode 100644 test/ip/basic_resolver_query_test.cpp create mode 100644 test/ip/host_name_test.cpp create mode 100644 test/ip/multicast_test.cpp create mode 100644 test/ip/resolver_query_base_test.cpp create mode 100644 test/ip/tcp_test.cpp create mode 100644 test/ip/udp_test.cpp create mode 100644 test/is_read_buffered_test.cpp create mode 100644 test/is_write_buffered_test.cpp create mode 100644 test/placeholders_test.cpp create mode 100644 test/read_test.cpp create mode 100644 test/resolver_service_test.cpp create mode 100644 test/socket_acceptor_service_test.cpp create mode 100644 test/socket_base_test.cpp create mode 100644 test/ssl/Jamfile create mode 100644 test/ssl/Jamfile.v2 create mode 100644 test/ssl/basic_context_test.cpp create mode 100644 test/ssl/context_base_test.cpp create mode 100644 test/ssl/context_service_test.cpp create mode 100644 test/ssl/context_test.cpp create mode 100644 test/ssl/stream_base_test.cpp create mode 100644 test/ssl/stream_service_test.cpp create mode 100644 test/ssl/stream_test.cpp create mode 100644 test/strand_service_test.cpp create mode 100644 test/strand_test.cpp create mode 100644 test/stream_socket_service_test.cpp create mode 100644 test/time_traits_test.cpp create mode 100644 test/unit_test.hpp create mode 100644 test/write_test.cpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..3e84d7c704 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/example/allocation/Jamfile b/example/allocation/Jamfile new file mode 100644 index 0000000000..5c7dbd3e8c --- /dev/null +++ b/example/allocation/Jamfile @@ -0,0 +1,25 @@ +subproject libs/asio/example/allocation ; + +project boost : $(BOOST_ROOT) ; + +if $(UNIX) +{ + switch $(JAMUNAME) + { + case SunOS* : + { + SOCKET_LIBS = socket nsl ; + } + } +} + +exe server + : server.cpp + : $(BOOST_ROOT) + ../../../.. + BOOST_ALL_NO_LIB=1 + multi + <*>ws2_32 + <*>mswsock + $(SOCKET_LIBS) + ; diff --git a/example/allocation/server.cpp b/example/allocation/server.cpp new file mode 100644 index 0000000000..ce73cca99f --- /dev/null +++ b/example/allocation/server.cpp @@ -0,0 +1,229 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using boost::asio::ip::tcp; + +// Class to manage the memory to be used for handler-based custom allocation. +// It contains a single block of memory which may be returned for allocation +// requests. If the memory is in use when an allocation request is made, the +// allocator delegates allocation to the global heap. +class handler_allocator + : private boost::noncopyable +{ +public: + handler_allocator() + : in_use_(false) + { + } + + void* allocate(std::size_t size) + { + if (!in_use_ && size < storage_.size) + { + in_use_ = true; + return storage_.address(); + } + else + { + return ::operator new(size); + } + } + + void deallocate(void* pointer) + { + if (pointer == storage_.address()) + { + in_use_ = false; + } + else + { + ::operator delete(pointer); + } + } + +private: + // Storage space used for handler-based custom memory allocation. + boost::aligned_storage<1024> storage_; + + // Whether the handler-based custom allocation storage has been used. + bool in_use_; +}; + +// Wrapper class template for handler objects to allow handler memory +// allocation to be customised. Calls to operator() are forwarded to the +// encapsulated handler. +template +class custom_alloc_handler +{ +public: + custom_alloc_handler(handler_allocator& a, Handler h) + : allocator_(a), + handler_(h) + { + } + + template + void operator()(Arg1 arg1) + { + handler_(arg1); + } + + template + void operator()(Arg1 arg1, Arg2 arg2) + { + handler_(arg1, arg2); + } + + friend void* asio_handler_allocate(std::size_t size, + custom_alloc_handler* this_handler) + { + return this_handler->allocator_.allocate(size); + } + + friend void asio_handler_deallocate(void* pointer, std::size_t size, + custom_alloc_handler* this_handler) + { + this_handler->allocator_.deallocate(pointer); + } + +private: + handler_allocator& allocator_; + Handler handler_; +}; + +// Helper function to wrap a handler object to add custom allocation. +template +inline custom_alloc_handler make_custom_alloc_handler( + handler_allocator& a, Handler h) +{ + return custom_alloc_handler(a, h); +} + +class session + : public boost::enable_shared_from_this +{ +public: + session(boost::asio::io_service& io_service) + : socket_(io_service) + { + } + + tcp::socket& socket() + { + return socket_; + } + + void start() + { + socket_.async_read_some(boost::asio::buffer(data_), + make_custom_alloc_handler(allocator_, + boost::bind(&session::handle_read, + shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + } + + void handle_read(const boost::asio::error& error, size_t bytes_transferred) + { + if (!error) + { + boost::asio::async_write(socket_, + boost::asio::buffer(data_, bytes_transferred), + make_custom_alloc_handler(allocator_, + boost::bind(&session::handle_write, + shared_from_this(), + boost::asio::placeholders::error))); + } + } + + void handle_write(const boost::asio::error& error) + { + if (!error) + { + socket_.async_read_some(boost::asio::buffer(data_), + make_custom_alloc_handler(allocator_, + boost::bind(&session::handle_read, + shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + } + } + +private: + // The socket used to communicate with the client. + tcp::socket socket_; + + // Buffer used to store data received from the client. + boost::array data_; + + // The allocator to use for handler-based custom memory allocation. + handler_allocator allocator_; +}; + +typedef boost::shared_ptr session_ptr; + +class server +{ +public: + server(boost::asio::io_service& io_service, short port) + : io_service_(io_service), + acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) + { + session_ptr new_session(new session(io_service_)); + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + + void handle_accept(session_ptr new_session, const boost::asio::error& error) + { + if (!error) + { + new_session->start(); + new_session.reset(new session(io_service_)); + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + } + +private: + boost::asio::io_service& io_service_; + tcp::acceptor acceptor_; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 2) + { + std::cerr << "Usage: server \n"; + return 1; + } + + boost::asio::io_service io_service; + + using namespace std; // For atoi. + server s(io_service, atoi(argv[1])); + + io_service.run(); + } + catch (boost::asio::error& e) + { + std::cerr << e << "\n"; + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} diff --git a/example/buffers/Jamfile b/example/buffers/Jamfile new file mode 100644 index 0000000000..16a045c2f1 --- /dev/null +++ b/example/buffers/Jamfile @@ -0,0 +1,25 @@ +subproject libs/asio/example/buffers ; + +project boost : $(BOOST_ROOT) ; + +if $(UNIX) +{ + switch $(JAMUNAME) + { + case SunOS* : + { + SOCKET_LIBS = socket nsl ; + } + } +} + +exe server + : reference_counted.cpp + : $(BOOST_ROOT) + ../../../.. + BOOST_ALL_NO_LIB=1 + multi + <*>ws2_32 + <*>mswsock + $(SOCKET_LIBS) + ; diff --git a/example/buffers/reference_counted.cpp b/example/buffers/reference_counted.cpp new file mode 100644 index 0000000000..f35c0fe42c --- /dev/null +++ b/example/buffers/reference_counted.cpp @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +using boost::asio::ip::tcp; + +// A reference-counted non-modifiable buffer class. +class shared_const_buffer +{ +public: + // Construct from a std::string. + explicit shared_const_buffer(const std::string& data) + : data_(new std::vector(data.begin(), data.end())), + buffer_(boost::asio::buffer(*data_)) + { + } + + // Implement the Const_Buffers concept. + typedef boost::asio::const_buffer value_type; + typedef const boost::asio::const_buffer* const_iterator; + const boost::asio::const_buffer* begin() const { return &buffer_; } + const boost::asio::const_buffer* end() const { return &buffer_ + 1; } + +private: + boost::shared_ptr > data_; + boost::asio::const_buffer buffer_; +}; + +class session + : public boost::enable_shared_from_this +{ +public: + session(boost::asio::io_service& io_service) + : socket_(io_service) + { + } + + tcp::socket& socket() + { + return socket_; + } + + void start() + { + using namespace std; // For time_t, time and ctime. + time_t now = time(0); + shared_const_buffer buffer(ctime(&now)); + boost::asio::async_write(socket_, buffer, + boost::bind(&session::handle_write, shared_from_this())); + } + + void handle_write() + { + } + +private: + // The socket used to communicate with the client. + tcp::socket socket_; +}; + +typedef boost::shared_ptr session_ptr; + +class server +{ +public: + server(boost::asio::io_service& io_service, short port) + : io_service_(io_service), + acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) + { + session_ptr new_session(new session(io_service_)); + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + + void handle_accept(session_ptr new_session, const boost::asio::error& error) + { + if (!error) + { + new_session->start(); + new_session.reset(new session(io_service_)); + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + } + +private: + boost::asio::io_service& io_service_; + tcp::acceptor acceptor_; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 2) + { + std::cerr << "Usage: reference_counted \n"; + return 1; + } + + boost::asio::io_service io_service; + + using namespace std; // For atoi. + server s(io_service, atoi(argv[1])); + + io_service.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} diff --git a/example/chat/Jamfile b/example/chat/Jamfile new file mode 100644 index 0000000000..0cc5bf7802 --- /dev/null +++ b/example/chat/Jamfile @@ -0,0 +1,38 @@ +subproject libs/asio/example/chat ; + +project boost : $(BOOST_ROOT) ; + +if $(UNIX) +{ + switch $(JAMUNAME) + { + case SunOS* : + { + SOCKET_LIBS = socket nsl ; + } + } +} + +exe chat_client + : @boost/libs/thread/build/boost_thread + chat_client.cpp + : $(BOOST_ROOT) + ../../../.. + BOOST_ALL_NO_LIB=1 + multi + <*>ws2_32 + <*>mswsock + $(SOCKET_LIBS) + ; + +exe chat_server + : @boost/libs/thread/build/boost_thread + chat_server.cpp + : $(BOOST_ROOT) + ../../../.. + BOOST_ALL_NO_LIB=1 + multi + <*>ws2_32 + <*>mswsock + $(SOCKET_LIBS) + ; diff --git a/example/chat/chat_client.cpp b/example/chat/chat_client.cpp new file mode 100644 index 0000000000..57876fba70 --- /dev/null +++ b/example/chat/chat_client.cpp @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include +#include "chat_message.hpp" + +using boost::asio::ip::tcp; + +typedef std::deque chat_message_queue; + +class chat_client +{ +public: + chat_client(boost::asio::io_service& io_service, + tcp::resolver::iterator endpoint_iterator) + : io_service_(io_service), + socket_(io_service) + { + tcp::endpoint endpoint = *endpoint_iterator; + socket_.async_connect(endpoint, + boost::bind(&chat_client::handle_connect, this, + boost::asio::placeholders::error, ++endpoint_iterator)); + } + + void write(const chat_message& msg) + { + io_service_.post(boost::bind(&chat_client::do_write, this, msg)); + } + + void close() + { + io_service_.post(boost::bind(&chat_client::do_close, this)); + } + +private: + + void handle_connect(const boost::asio::error& error, + tcp::resolver::iterator endpoint_iterator) + { + if (!error) + { + boost::asio::async_read(socket_, + boost::asio::buffer(read_msg_.data(), chat_message::header_length), + boost::bind(&chat_client::handle_read_header, this, + boost::asio::placeholders::error)); + } + else if (endpoint_iterator != tcp::resolver::iterator()) + { + socket_.close(); + tcp::endpoint endpoint = *endpoint_iterator; + socket_.async_connect(endpoint, + boost::bind(&chat_client::handle_connect, this, + boost::asio::placeholders::error, ++endpoint_iterator)); + } + } + + void handle_read_header(const boost::asio::error& error) + { + if (!error && read_msg_.decode_header()) + { + boost::asio::async_read(socket_, + boost::asio::buffer(read_msg_.body(), read_msg_.body_length()), + boost::bind(&chat_client::handle_read_body, this, + boost::asio::placeholders::error)); + } + else + { + do_close(); + } + } + + void handle_read_body(const boost::asio::error& error) + { + if (!error) + { + std::cout.write(read_msg_.body(), read_msg_.body_length()); + std::cout << "\n"; + boost::asio::async_read(socket_, + boost::asio::buffer(read_msg_.data(), chat_message::header_length), + boost::bind(&chat_client::handle_read_header, this, + boost::asio::placeholders::error)); + } + else + { + do_close(); + } + } + + void do_write(chat_message msg) + { + bool write_in_progress = !write_msgs_.empty(); + write_msgs_.push_back(msg); + if (!write_in_progress) + { + boost::asio::async_write(socket_, + boost::asio::buffer(write_msgs_.front().data(), + write_msgs_.front().length()), + boost::bind(&chat_client::handle_write, this, + boost::asio::placeholders::error)); + } + } + + void handle_write(const boost::asio::error& error) + { + if (!error) + { + write_msgs_.pop_front(); + if (!write_msgs_.empty()) + { + boost::asio::async_write(socket_, + boost::asio::buffer(write_msgs_.front().data(), + write_msgs_.front().length()), + boost::bind(&chat_client::handle_write, this, + boost::asio::placeholders::error)); + } + } + else + { + do_close(); + } + } + + void do_close() + { + socket_.close(); + } + +private: + boost::asio::io_service& io_service_; + tcp::socket socket_; + chat_message read_msg_; + chat_message_queue write_msgs_; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 3) + { + std::cerr << "Usage: chat_client \n"; + return 1; + } + + boost::asio::io_service io_service; + + tcp::resolver resolver(io_service); + tcp::resolver::query query(argv[1], argv[2]); + tcp::resolver::iterator iterator = resolver.resolve(query); + + chat_client c(io_service, iterator); + + boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); + + char line[chat_message::max_body_length + 1]; + while (std::cin.getline(line, chat_message::max_body_length + 1)) + { + using namespace std; // For strlen and memcpy. + chat_message msg; + msg.body_length(strlen(line)); + memcpy(msg.body(), line, msg.body_length()); + msg.encode_header(); + c.write(msg); + } + + c.close(); + t.join(); + } + catch (boost::asio::error& e) + { + std::cerr << e << "\n"; + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} diff --git a/example/chat/chat_message.hpp b/example/chat/chat_message.hpp new file mode 100644 index 0000000000..156765275b --- /dev/null +++ b/example/chat/chat_message.hpp @@ -0,0 +1,83 @@ +#ifndef CHAT_MESSAGE_HPP +#define CHAT_MESSAGE_HPP + +#include +#include +#include + +class chat_message +{ +public: + enum { header_length = 4 }; + enum { max_body_length = 512 }; + + chat_message() + : body_length_(0) + { + } + + const char* data() const + { + return data_; + } + + char* data() + { + return data_; + } + + size_t length() const + { + return header_length + body_length_; + } + + const char* body() const + { + return data_ + header_length; + } + + char* body() + { + return data_ + header_length; + } + + size_t body_length() const + { + return body_length_; + } + + void body_length(size_t length) + { + body_length_ = length; + if (body_length_ > max_body_length) + body_length_ = max_body_length; + } + + bool decode_header() + { + using namespace std; // For strncat and atoi. + char header[header_length + 1] = ""; + strncat(header, data_, header_length); + body_length_ = atoi(header); + if (body_length_ > max_body_length) + { + body_length_ = 0; + return false; + } + return true; + } + + void encode_header() + { + using namespace std; // For sprintf and memcpy. + char header[header_length + 1] = ""; + sprintf(header, "%4d", body_length_); + memcpy(data_, header, header_length); + } + +private: + char data_[header_length + max_body_length]; + size_t body_length_; +}; + +#endif // CHAT_MESSAGE_HPP diff --git a/example/chat/chat_server.cpp b/example/chat/chat_server.cpp new file mode 100644 index 0000000000..dafb733afc --- /dev/null +++ b/example/chat/chat_server.cpp @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "chat_message.hpp" + +using boost::asio::ip::tcp; + +//---------------------------------------------------------------------- + +typedef std::deque chat_message_queue; + +//---------------------------------------------------------------------- + +class chat_participant +{ +public: + virtual ~chat_participant() {} + virtual void deliver(const chat_message& msg) = 0; +}; + +typedef boost::shared_ptr chat_participant_ptr; + +//---------------------------------------------------------------------- + +class chat_room +{ +public: + void join(chat_participant_ptr participant) + { + participants_.insert(participant); + std::for_each(recent_msgs_.begin(), recent_msgs_.end(), + boost::bind(&chat_participant::deliver, participant, _1)); + } + + void leave(chat_participant_ptr participant) + { + participants_.erase(participant); + } + + void deliver(const chat_message& msg) + { + recent_msgs_.push_back(msg); + while (recent_msgs_.size() > max_recent_msgs) + recent_msgs_.pop_front(); + + std::for_each(participants_.begin(), participants_.end(), + boost::bind(&chat_participant::deliver, _1, boost::ref(msg))); + } + +private: + std::set participants_; + enum { max_recent_msgs = 100 }; + chat_message_queue recent_msgs_; +}; + +//---------------------------------------------------------------------- + +class chat_session + : public chat_participant, + public boost::enable_shared_from_this +{ +public: + chat_session(boost::asio::io_service& io_service, chat_room& room) + : socket_(io_service), + room_(room) + { + } + + tcp::socket& socket() + { + return socket_; + } + + void start() + { + room_.join(shared_from_this()); + boost::asio::async_read(socket_, + boost::asio::buffer(read_msg_.data(), chat_message::header_length), + boost::bind( + &chat_session::handle_read_header, shared_from_this(), + boost::asio::placeholders::error)); + } + + void deliver(const chat_message& msg) + { + bool write_in_progress = !write_msgs_.empty(); + write_msgs_.push_back(msg); + if (!write_in_progress) + { + boost::asio::async_write(socket_, + boost::asio::buffer(write_msgs_.front().data(), + write_msgs_.front().length()), + boost::bind(&chat_session::handle_write, shared_from_this(), + boost::asio::placeholders::error)); + } + } + + void handle_read_header(const boost::asio::error& error) + { + if (!error && read_msg_.decode_header()) + { + boost::asio::async_read(socket_, + boost::asio::buffer(read_msg_.body(), read_msg_.body_length()), + boost::bind(&chat_session::handle_read_body, shared_from_this(), + boost::asio::placeholders::error)); + } + else + { + room_.leave(shared_from_this()); + } + } + + void handle_read_body(const boost::asio::error& error) + { + if (!error) + { + room_.deliver(read_msg_); + boost::asio::async_read(socket_, + boost::asio::buffer(read_msg_.data(), chat_message::header_length), + boost::bind(&chat_session::handle_read_header, shared_from_this(), + boost::asio::placeholders::error)); + } + else + { + room_.leave(shared_from_this()); + } + } + + void handle_write(const boost::asio::error& error) + { + if (!error) + { + write_msgs_.pop_front(); + if (!write_msgs_.empty()) + { + boost::asio::async_write(socket_, + boost::asio::buffer(write_msgs_.front().data(), + write_msgs_.front().length()), + boost::bind(&chat_session::handle_write, shared_from_this(), + boost::asio::placeholders::error)); + } + } + else + { + room_.leave(shared_from_this()); + } + } + +private: + tcp::socket socket_; + chat_room& room_; + chat_message read_msg_; + chat_message_queue write_msgs_; +}; + +typedef boost::shared_ptr chat_session_ptr; + +//---------------------------------------------------------------------- + +class chat_server +{ +public: + chat_server(boost::asio::io_service& io_service, + const tcp::endpoint& endpoint) + : io_service_(io_service), + acceptor_(io_service, endpoint) + { + chat_session_ptr new_session(new chat_session(io_service_, room_)); + acceptor_.async_accept(new_session->socket(), + boost::bind(&chat_server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + + void handle_accept(chat_session_ptr session, const boost::asio::error& error) + { + if (!error) + { + session->start(); + chat_session_ptr new_session(new chat_session(io_service_, room_)); + acceptor_.async_accept(new_session->socket(), + boost::bind(&chat_server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + } + +private: + boost::asio::io_service& io_service_; + tcp::acceptor acceptor_; + chat_room room_; +}; + +typedef boost::shared_ptr chat_server_ptr; +typedef std::list chat_server_list; + +//---------------------------------------------------------------------- + +int main(int argc, char* argv[]) +{ + try + { + if (argc < 2) + { + std::cerr << "Usage: chat_server [ ...]\n"; + return 1; + } + + boost::asio::io_service io_service; + + chat_server_list servers; + for (int i = 1; i < argc; ++i) + { + using namespace std; // For atoi. + tcp::endpoint endpoint(tcp::v4(), atoi(argv[i])); + chat_server_ptr server(new chat_server(io_service, endpoint)); + servers.push_back(server); + } + + io_service.run(); + } + catch (boost::asio::error& e) + { + std::cerr << e << "\n"; + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} diff --git a/example/echo/Jamfile b/example/echo/Jamfile new file mode 100644 index 0000000000..54a561f1eb --- /dev/null +++ b/example/echo/Jamfile @@ -0,0 +1,55 @@ +subproject libs/asio/example/echo ; + +project boost : $(BOOST_ROOT) ; + +if $(UNIX) +{ + switch $(JAMUNAME) + { + case SunOS* : + { + SOCKET_LIBS = socket nsl ; + } + } +} + +template asio_echo_example + : @boost/libs/thread/build/boost_thread + : $(BOOST_ROOT) + ../../../.. + BOOST_ALL_NO_LIB=1 + multi + <*>ws2_32 + <*>mswsock + $(SOCKET_LIBS) + ; + +exe async_tcp_echo_server + :