About Poco: The TCPServer framework (the select model is used in windows) learning notes., pocotcpserver. Notes about Poco: TCPServer framework (the select model is used in windows ., pocotcpserver explains why I want to write this article. I have read the Poco: TCPServer box of A'er dream ship about Poco: TCPServer framework (the select model is used in windows) study notes ., pocotcpserver
Description
Why should I write this article? I have read A'er dream ship before. Http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html
There are too many code, which seems complicated. Therefore, the preparation is simplified with a flowchart for easy understanding and future use.
This article is based on window api analysis.
The poco version in this article is 1.4.6p4 (). Although the current poco version is 1.6, the call is not changed much.
Poco: http://pocoproject.org/releases/
This article analyzes TimeServer. cpp as the entry point:
Before the start:
1. Inline functions: see:
Http://blog.sina.com.cn/s/blog_90e888f50100zgo2.html
It mainly improves the execution efficiency.
2. overload, rewriting, and hiding of class member functions,
Refer:
Dazhong159 <类成员函数的重载、重写、和覆盖区别>
Http://blog.csdn.net/dazhong159/article/details/7844369
Code is widely used, overwritten, and hidden.
3. principle of the select Model:
Reference
Humorous explanation of six Socket I/O models
Http://blog.csdn.net/normalnotebook/article/details/999840
Content:
For I: = 0 to fd_read.fd_count-1 do // note, fd_count <= 64, that is, select can only manage up to 64 connections at the same time
Is a synchronization operation.
Chen wanted to hear from his daughter. So that he goes downstairs every 10 minutes to check whether he has a daughter's email ~~~~~
In this case, "going downstairs to check the mailbox" and going back to the upstairs has delayed Lao Chen's time, so that he cannot do other work.
The select model is very similar to the old Chen model in this case: check again and again... 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) do begin FD_ZERO (fd_read ); FD_SET (MainSock, fd_read); timeout. TV _sec: = 0; timeout. TV _usec: = 500; if select (0, @ fd_read, nil, nil, @ timeout)> 0 then // at least one connection begin if FD_ISSET (MainSock, fd_read) then begin for I: = 0 to fd_read.fd_count-1 do // note, fd_count <= 64, that is, select can only manage up to 64 connections simultaneously begin len: = sizeof (addr ); ASock: = accept (MainSock, addr, len); if ASock <> INVALID_SOCKET then .... // create a new thread for ASock and select 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 acceptable.
4,
Understanding of the initialization sequence of constructors
The C ++ constructor is called in the following order:
(1) constructor of any virtual base class is constructed in the order they are inherited;
(2) any non-virtual base class constructor is constructed in the order they are inherited;
(3) constructors of any member objects are called in the order they are declared;
(4) class self-built functions.
5. about the FastMutex mutex variable
Bool NotificationQueue: empty () const
{
FastMutex: ScopedLock lock (_ mutex );
Return _ nfQueue. empty ();
}
Call after empty () is executed ~ FastMutex: ScopedLock Destructor to release.
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 section
};
You can see the critical section used in windows.
6. about threads:
Use in window
_ Thread = (HANDLE) _ beginthreadex (NULL, _ stackSize, ent, this, 0, & threadId );
Executes the thread operation.
7. wait for the event. the synchronization of connection requests is used.
WaitForSingleObject (this is my favorite)
Use SetEvent () and ResetEvent () to activate reset.
8. Use of static_cast <> reinterpret_cast <> dynamic_cast <>.
Refer:
Http://www.cnblogs.com/bastard/archive/2011/12/14/2288117.html
Http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html
Like in the code:
Void * pThread;
Reinterpret_cast (PThread)-> _ pRunnableTarget-> run ();
// The reinterpret_cas conversion is the most "insecure". the conversion between two class pointers without any relationship can be implemented using this conversion. for example:
_ ThreadId = static_cast (ThreadId );
// Static_cast is used for basic data type conversion (char, int) and conversion between pointers.
9. About the Smart (smart) pointer auto_ptr.
Auto_ptr to put it simply, it is to ensure that the created resources are free when they exit (whether there are exceptions or not)
Std: auto_ptr PConnection (_ pConnectionFactory-> createConnection (pCNf-> socket ()));
AutoPtr PNf = _ queue. waitDequeueNotification (idleTime );
You can directly .
Template
Class auto_ptr
{// Wrap an object pointer to ensure destruction
Refer:
More Effective c0000.pdf Chinese version 7.4 Item M28: smart pointer chapter (baidu found download)
Http://blog.chinaunix.net/uid-9525959-id-2001803.html
Segment in:
How to avoid auto_ptr defects
Auto_ptr is not perfect. it is indeed very convenient, but it also has defects. avoid it when using it. First, do not use the auto_ptr object as an element of the STL container. The C ++ standard explicitly prohibits such operations, otherwise unexpected results may occur.
Another defect of auto_ptr is that the array is used as the parameter of auto_ptr:
Auto_ptr Pstr (new char [12]); // array; defined
Remember to use delete [] to destroy the array no matter when the new operation of the array is used. Because the destructor of auto_ptr only applies to non-array types. Therefore, if arrays cannot be correctly destroyed, the program's behavior is unclear. In short, auto_ptr controls a single object pointer allocated by new. that's all.
However, the C ++ 11 standard solves this problem:
Unique_ptr
Smart pointer with unique object ownership semantics
Only one master pointer can be used for STL containers.
Shared_ptr
Smart pointer with shared object ownership semantics
Shared pointer
Weak_ptr
Weak reference to an object managed by std: shared_ptr
Weak reference pointer
Auto_ptr
Smart pointer with strict object ownership semantics
Only one master pointer is allowed and cannot be used in STL containers.
If you want to go deep (do not think too much-_-), Please baidu...
After reading the above, I found that I think all kinds of knowledge have been consolidated.
So we still need to look at the source code. The company did not need to open source before it went through...
Start
Main use of class relationships in code
The image is too wide and cannot be displayed (please open the image in the new tag. thank you .)
Main categories:
1. the TCPServer Master Service is responsible for calling the select Model to handle connection message changes.
2. PooledThread is the thread pool. when activated, TCPServerDispatcher: run () is called to process the specific request after the packet is received. TCPServerDispatcher: run () is called
TimeServerConnection. run (). TimeServerConnection. run.
3. TCPServerDispatcher: the dispatch manager (call this first). receives message changes and puts them in the queue. manages connections.
When put into the queue, events in PooledThread will be activated.
PooledThread in turn activates TCPServerDispatcher: run () [activate each other when conditions are met]
4. TCPServerConnection. to implement specific behavior, the function is defined by inheriting the run () of the subclass.
5. TCPServerConnectionFactory is responsible for creating and managing TCPServerConnection.
6. TCPServerParams parameter management. you know.
7. icationicationqueue puts the connection into the queue for management.
After reading the introduction of several main classes, other procedures should be well understood.
Flowchart:
Because the graph is too long,
The image is too wide and cannot be displayed (please open the image in the new tag. thank you .)
Let's take a look at the process of PooledThread.
Let's look at the process dominated by TCPServer.
The image is too wide and cannot be displayed (please open the image in the new tag. thank you .)
In windows, select does not have good performance, but in linux, epoll is used.
Epoll is more efficient than select. see: http://blog.csdn.net/legion8169/article/details/1637154.
However, poco tcpserver has Thread pool operations, so the efficiency is not too low.
First come here, not finished yet.
What can we change:
ThreadPool(int minCapacity = 2, int maxCapacity = 16, int idleTime = 60, int stackSize = POCO_THREAD_STACK_SIZE); /// Creates a thread pool with minCapacity threads. /// If required, up to maxCapacity threads are created /// a NoThreadAvailableException exception is thrown. /// If a thread is running idle for more than idleTime seconds, /// and more than minCapacity threads are running, the thread /// is killed. Threads are created with given stack size.
Increase the number of threads in the thread pool !), To speed up processing in the select statement.
In a medium program, the TCPSelect Manage process is added to communicate with multiple TcpServer processes.
That is, add another manager (intermediate key, activemq, and so on) to enhance the concurrency capability,
Or you can directly use the linux environment, that is, epoll is used for efficiency.
You may not be able to understand it.
Thank you.
Objective Poco: TCPServer framework (the select model is used in windows) learning notes ., pocotcpserver explains why to write this article. I have read the Poco: TCPServer box of A'er dream ship before...