Learn notes about the Poco::tcpserver framework (the Select model used under Windows)., Pocotcpserver
Description
Why write this article, have seen the http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html of Ayi's dream ship before
Helpless code too much, look cumbersome. So be prepared to streamline with flowcharts, easy to understand. Also convenient for later use.
This article is based on the window API analysis.
Poco in this article is version 1.4.6p4 (2014-04-18). Although the Poco version is now 1.6, the call does not change much.
Poco Download Address: http://pocoproject.org/releases/
This paper analyses the TimeServer.cpp as the entrance analysis:
About before you start:
1,inline Inline function: You can refer to:
Http://blog.sina.com.cn/s/blog_90e888f50100zgo2.html
Mainly to improve the efficiency of implementation.
2, overloading of class member functions, overriding, hiding,
Reference:
Dazhong159 's <类成员函数的重载、重写、和覆盖区别>
http://blog.csdn.net/dazhong159/article/details/7844369
The code is heavily used, rewritten, hidden.
The principle of the 3,select model:
Reference
Very humorous. Six types of socket I/O models
http://blog.csdn.net/normalnotebook/article/details/999840
The content of:
For i:=0 to Fd_read.fd_count-1 do//note, Fd_count <= 64, which means select can manage up to 64 connections at the same time
is a synchronous operation.
Lao Chen wanted to see his daughter's letter very much. So that he went downstairs every 10 minutes to check the mailbox to see if he had a daughter's letter ~~~~~
In this case, "go downstairs to check the mailbox" and then back upstairs to delay the old Chen too much time, so that Lao Chen can not do other work.
The Select model is very similar to that of old Chen: Go round and round to check ... If there is data ... Receive/Send ....
..... Mainsock:=socket (af_inet, sock_stream, ipproto_tcp); addr.sin_family:=af_inet; Addr.sin_port:= Htons (5678); Addr.sin_addr. S_ADDR:=htonl (Inaddr_any); Bind (Mainsock, @addr,sizeof(addr)); Listen (Mainsock,5 ); while(Not Terminated) Dobegin Fd_zero (fd_read); Fd_set (Mainsock, fd_read); Timeout.tv_sec:=0; Timeout.tv_usec:= -; if Select(0, @fd_read, nil, nil, @timeout) >0Then//there are at least 1 connection waiting for the AcceptbeginifFd_isset (Mainsock, fd_read) THEN BEGIN fori:=0To fd_read.fd_count-1 Do //Note that Fd_count <= 64, which means select can manage up to 64 connections at a timebegin Len:=sizeof(addr); Asock:=Accept (Mainsock, addr, len);ifAsock <>Invalid_socket then ....//Create a new thread for Asock, and in the new thread, selectend; End End End //While, not self . Terminated)shutdown (Mainsock, sd_both); closesocket (mainsock); end;
Therefore, the Select model can only be used for general small connections .... High concurrency is not possible.
4,
Understanding of the initialization order of constructors
The C + + constructors are called in the following order:
(1) The constructors of any virtual base class are constructed in the order in which they are inherited;
(2) The constructors of any non-virtual base class are constructed in the order in which they are inherited;
(3) The constructors of any member object are invoked in the order in which they are declared;
(4) class-own constructors.
5, about Fastmutex mutex variables
BOOL Notificationqueue::empty () const
{
Fastmutex::scopedlock Lock (_mutex);
return _nfqueue.empty ();
}
The ~fastmutex::scopedlock destructor is called after empty () execution completes to release.
Below window is the critical section used:
Class Foundation_api Muteximpl
{
Protected
Muteximpl ();
~muteximpl ();
void Lockimpl ();
BOOL Trylockimpl ();
BOOL Trylockimpl (long milliseconds);
void Unlockimpl ();
Private
critical_section _cs;//Critical Zone
};
You can see the critical section used by Windows under the environment.
6, about Threads:
Use under Window
_thread = (HANDLE) _beginthreadex (NULL, _stacksize, ENT, this, 0, &threadid);
Executes the operation of the thread.
7, wait for the event, the synchronization of the connection request is used
WaitForSingleObject ( This is my favorite too )
The reset is activated by SetEvent (), ResetEvent ().
Use of 8,static_cast<> reinterpret_cast<> dynamic_cast<>.
Refer to:
Http://www.cnblogs.com/bastard/archive/2011/12/14/2288117.html
Http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html
Like in code:
void* PThread;
Reinterpret_cast (PThread)->_prunnabletarget->run ();
Reinterpret_cas This conversion is the most "unsafe", the conversion between two classes that do not have any relation between pointers can be implemented with this conversion, for example
_threadid = static_cast (threadId);
Static_cast for basic data type conversions (Char,int), and conversions between pointers
9, about Smart (dexterous) pointer auto_ptr.
Auto_ptr, simply put, is to ensure that the created resource can be free at exit (with or without exception)
Std::auto_ptr pconnection (_pconnectionfactory->createconnection (Pcnf->socket ()));
Autoptr pNf = _queue.waitdequeuenotification (idleTime);
Can be found directly in the
Template
Class Auto_ptr
{//Wrap an object pointer to ensure destruction
can refer to:
More effective C + + Chinese version. pdf 7.4 Item M28: Smart (SMART) pointer chapter (Baidu check to download)
Http://blog.chinaunix.net/uid-9525959-id-2001803.html
In the Fragment:
How to avoid the use of auto_ptr defects
Auto_ptr is not perfect, it is very convenient, but there are defects, in use should be careful to avoid. first, do not use the Auto_ptr object as an element of the STL container. This is expressly prohibited by the C + + standard, which may result in unforeseen results.
Another drawback of auto_ptr is the use of arrays as Auto_ptr parameters:
Auto_ptr pstr (new char[12]);//arrays; for definition
Remember that whenever you use the new operation of an array, you must use delete[] to destroy the array. Because the destructor of auto_ptr only works on non-array types. So the array is not destroyed correctly, the behavior of the program is not clear. In summary, auto_ptr controls a single-object pointer assigned by new, which is all.
However, this problem is addressed in the C + + 11 standard:
Unique_ptr
Smart pointer with unique object ownership semantics
Only one master pointer can be used for the STL container
shared_ptr
Smart pointer with shared object ownership semantics
Shareable pointers
Weak_ptr
Weak reference to a object managed by Std::shared_ptr
Weak reference pointers
Auto_ptr
Smart pointer with strict object ownership semantics
Can only have one master pointer, cannot be used in STL container
Go far, want to deep (don't think more-_-), please Baidu ...
After reading the above, it is found that all kinds of knowledge has been consolidated.
So still want to see open source code, before the company died without open source ... Hey...
Begin
The main use of class relationships in code
The picture is too wide to display (please open the picture in a new tab.)
The main categories are:
1,tcpserver the master service, which is responsible for invoking the Select model to handle changes in the connection message.
2,pooledthread is a thread pool. When activated, call Tcpserverdispatcher::run () to handle the specific request after the packet is received. and Tcpserverdispatcher::run () calls
Timeserverconnection.run (). Timeserverconnection.run () implements the programmer's custom function through subclass hiding. Have to write about the interests of the Poco Daniel.
3,tcpserverdispatcher, dispatch the manager (call it first). Receives a message change and puts it in the queue. Manage the number of connections.
Events in Pooledthread are activated when the queue is placed.
Pooledthread in turn activates Tcpserverdispatcher::run () [Let's activate each other when conditional]
4,tcpserverconnection. Implement specific behavior by inheriting the subclass's run () to customize the implementation functionality.
5,tcpserverconnectionfactory is responsible for creating and managing tcpserverconnection.
6,tcpserverparams This parameter management, do not say. You know.
7,notificationqueue the connection into the queue. Manage.
After reading the main categories of the introduction, other processes should understand the approximate.
Flow chart:
Because the graph is too long in relation to many,
The picture is too wide to display (please open the picture in a new tab.)
Let's take a look at the pooledthread process.
And take a look at the process of TCPServer dominance.
The picture is too wide to display (please open the picture in a new tab.)
The select under Windows does not perform well, and the Linux version is the Epoll.
Epoll relative Select to be efficient points. For reference: http://blog.csdn.net/legion8169/article/details/1637154
But the Poco tcpserver is a thread pool operation, so the efficiency is not too low.
Come here first, not finished yet.
What we can change:
ThreadPool (int2, int ,int60 , int stackSize = poco_thread_stack_size); /// creates a thread pool with mincapacity threads. /// If required, up to maxcapacity threads is created /// A Nothreadavailableexception exception is thrown. /// If A thread is running idle for more than idleTime seconds, /// and more than mincapacity threads is running, the thread /// Is killed. Threads is created with given stack size.
Increase the number of threads in the thread pool (crap!) to speed up the select process.
In a medium program, increase the Tcpselect manage process to be responsible for communicating with multiple tcpserver processes.
Add another manager (middle key, or ACTIVEMQ, etc.) to enhance concurrency,
or directly using the Linux environment, Epoll is used to achieve efficiency.
Personal humble opinion, may be some did not write understand. Still looking for expert guidance.
Thank you.
http://www.bkjia.com/PHPjc/971772.html www.bkjia.com true http://www.bkjia.com/PHPjc/971772.html techarticle Learn notes about the Poco::tcpserver framework (using the Select Model under Windows)., Pocotcpserver explains why to write this article, before seeing Ayi's dream ship's poco::tcpserver box ...