If you are accidentally browsing here, please look first
Source Code and routines:
Command line: SVN checkout Http://st-asio-wrapper.googlecode.com/svn/trunk/st-asio-wrapper-read-only
If you open it from the SVN client interface, just enter http://st-asio-wrapper.googlecode.com/svn/trunk/to the address bar
git:https://github.com/youngwolf-project/st_asio_wrapper/, in addition, my resources are also downloaded, but not the latest.
QQ Exchange Group: 198941541
VI: Development Tutorials (server side)
Server directly include St_asio_wrapper_server.h, you can implement a simple service side, as follows (also demonstrated an echo server, so inherited St_server wrote a Echo_server Class):
//Configuration#defineServer_port 9527#defineReuse_object//Use objects Pool//#define Force_to_use_msg_recv_buffer//Force to use the msg recv buffer#defineEnhanced_stability//Configuration#include"St_asio_wrapper_server.h" using namespaceSt_asio_wrapper; #defineQuit_command "Quit"#defineRestart_command "RESTART"#defineList_all_client "List_all_client"#defineList_status "STATUS"#defineSuspend_command "SUSPEND"#defineResume_command "Resume"//Demonstrate how to use custom Packer//in the default behavior, every st_tcp_socket have their own packer, and cause memory waste//at here, we make every echo_socket with the same global packer for memory saving//Notice:do not does this for Unpacker, because Unpacker have member variables and can ' t share each otherAuto Global_packer (boost::make_shared<packer>()); //demonstrates how to control the type of st_server_socket_base::server from template parametersclassI_echo_server: PublicI_server { Public: Virtual voidTest () =0; }; classEcho_socket: PublicSt_server_socket_base<boost::asio::ip::tcp::socket, i_echo_server> { Public: Echo_socket (i_server&Server_): St_server_socket_base (Server_) {Inner_packer (global_packer);} Public: //because we use objects pool (reuse_object been defined), so, strictly speaking, this virtual//function must is rewrote, but we don ' t has member variables to initialize but invoke father ' s//Reset () directly, so, it can is omitted, but we keep it for possibly the future usingVirtual voidReset () {St_server_socket_base::reset ();} protected: Virtual voidOn_recv_error (Consterror_code&EC) { //the type of st_server_base::server now can is controled by derived class (Echo_socket),//which is actually i_echo_server, so, we can invoke i_echo_server::test virtual function. server.test (); St_server_socket_base::on_recv_error (EC); } //msg handling:send the original msg back (echo server)#ifndef Force_to_use_msg_recv_buffer//This virtual function doesn ' t exists if force_to_use_msg_recv_buffer been definedVirtual BOOLOn_msg (msg_ctype& msg) {post_msg (msg);return false;} #endif //we should handle the MSG in On_msg_handle to time-consuming task like this:Virtual voidOn_msg_handle (msg_ctype&msg) {post_msg (msg);} //Please remember the defined Force_to_use_msg_recv_buffer, so, St_tcp_socket would directly//Use the msg recv buffer, and we need not rewrite on_msg (), which doesn ' t exist//msg Handling End}; classEcho_server: PublicSt_server_base<echo_socket, St_object_pool<echo_socket>, i_echo_server> { Public: Echo_server (st_service_pump&service_pump_): St_server_base (SERVICE_PUMP_) {}//From i_echo_server, pure virtual function, we must implement it. Virtual voidTest () {/*puts ("in Echo_server::test ()");*/} }; intMain () {puts ("type quit to end these the servers."); STD::stringstr; St_service_pump Service_pump; St_server Server_ (Service_pump); //Only need a simple server? Can directly use St_serverserver_.set_server_addr (Server_port+ -); Echo_server Echo_server_ (service_pump); //Echo ServerService_pump.start_service (1); while(Service_pump.is_running ()) {std::cin>>str; if(str = =Quit_command) Service_pump.stop_service (); Else if(str = =Restart_command) {Service_pump.stop_service (); Service_pump.start_service (1); } Else if(str = =list_status) {printf ("Normal Server:\nvalid Links:"Size_t_format", closed Links:"Size_t_format"\ n", Server_.size (), server_.closed_object_size ()); printf ("echo Server:\nvalid Links:"Size_t_format", closed Links:"Size_t_format"\ n", Echo_server_.size (), echo_server_.closed_object_size ()); } //the following-commands demonstrate how to suspend msg dispatching, no matter recv buffer been used or notElse if(str = =Suspend_command) Echo_server_.do_something_to_all (Boost::bind (&echo_socket::suspend_dispatch_msg, _1,true)); Else if(str = =Resume_command) Echo_server_.do_something_to_all (Boost::bind (&echo_socket::suspend_dispatch_msg, _1,false)); Else if(str = =list_all_client) {Puts ("clients from normal server:"); Server_.list_all_object (); Puts ("clients from Echo server:"); Echo_server_.list_all_object (); } Elseserver_.broadcast_msg (str); } return 0; } //Restore Configuration#undefServer_port#undefReuse_object//Use objects Pool//#undef Force_to_use_msg_recv_buffer//Force to use the msg recv buffer#undefEnhanced_stability//Restore Configuration
In the above example, the server receives data from the console, invokes Broadcast_msg broadcast data, and outputs it to the console (St_tcp_socket implementation) when the data is received;
where St_server Server_; This line applies for a common server, its function is simply to send receive messages, accept the connection. In general, just like the client in tutorial one, you need to inherit a socket class from St_server_socket and inherit a service class from St_server. To this end, the server demo also demonstrates an echo servers, which will send back any data received (you can learn to do an echo client, but do not echo the service side with the Echo client to work together, or Die loop.)
Start_service Open Service, Stop_service end service (must be explicitly called when exiting), is_running determine the running state of the service; If you want to modify the server-side address, call Set_server_ before calling Start_service addr function;
After Stop_service, you can call Start_service to start the service again;
Note: St_server's del_client is typically used to passively delete a client on the server (i.e., in the event of an error, such as in St_tcp_socket On_recv_error and On_send_error, see St_ Server_socket); If you want to actively shut down a client, it is recommended to call the client's Force_close or graceful_close (St_tcp_socket implementation) function, and their calls will eventually cause On_ Recv_error's call;
St_server's close_all_client actively shuts down all clients, such as when the server exits (Stop_service is automatically called);
Override St_server's on_accept function to determine whether to accept the client's connection and accept the return true based on your own policy;
St_server maintains a linked list (St_object_pool implementation) for saving all of the client (this brings several benefits: first, it is very convenient when broadcasting the message, second, it can turn on the function of automatic cleanup of a similar garbage collection mechanism that has been closed; Can turn on the object pool function), if you want to manage these clients yourself, you can return false in On_accept, then save it in your container and call start (St_server_socket implementation) to start accepting data (only once);
Of course, you can also save a client while returning True (stop calling start at this point), which does not result in much memory consumption, since it is wrapped with a smart pointer, and copying a copy simply adds a reference count. As to what is the advantage of doing this, if you do not think that you do not need, when you have the need, you will naturally know what is the use of, I just told you can do so, have an impression;
For a rewrite of on_msg or on_msg_handle, see Tutorial Fourth.
Boost.asio Packaging Class St_asio_wrapper development tutorial (2013.12.8 Update) (ii)