Description
Why write this article, have seen Ayi's dream Ship's <poco::tcpserver framework Analysis > http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html
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: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 < class member functions for overloading, overriding, and overriding differences >
http://blog.csdn.net/dazhong159/article/details/7844369
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
};
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<threadimpl*> (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<dword> (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<tcpserverconnection> pconnection (_pconnectionfactory->createconnection (PCNf->socket () ));
autoptr<notification> pNf = _queue.waitdequeuenotification (idleTime);
Can be found directly in <memory>
Template<class _ty>
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<char> pstr (new char[12]); Array; for defining
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 functionality through subclass shadowing. Have to write about the interests of 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.
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.)
Come here first, not finished yet.
What we can change:
ThreadPool (intMincapacity =2, intMaxcapacity = -, intIdleTime = -, intStackSize =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.
Personal humble opinion, may be some did not write understand. Still looking for expert guidance.
Thank you.
Learn notes about the Poco::tcpserver framework (the Select model used under Windows).