Sign In
Scalability Notes
[Read -> Think -> Write]
Translate This Page
Translate this page
Powered by
Microsoft® Translator
Options
Blog Home
Email Blog Author
Share this
RSS for posts
RSS for comments
Search
Advanced search options...
Search In:
Everything
Blogs
Forums
People
Groups
Places
Pages
Date range:
All Time
Last Year
Last 6 Months
Last 3 Months
Last Month
Last Week
Last Two Days
Tags
database
distributed system
engineering
hpc
network
parallel
scalability
search
Archive
Archives
December 2010
(1)
September 2010
(1)
August 2010
(1)
April 2010
(1)
February 2010
(2)
January 2010
(4)
December 2009
(1)
November 2009
(1)
October 2009
(1)
September 2009
(1)
August 2009
(4)
June 2009
(2)
May 2009
(1)
April 2009
(1)
March 2009
(2)
February 2009
(4)
January 2009
(1)
Winsock I/O Model - Part II : Implementation
MSDN Blogs
>
Scalability Notes
>
Winsock I/O Model - Part II : Implementation
Winsock I/O Model - Part II : Implementation
changl
18 Aug 2009 1:41 AM
Comments
0
Winsock I/O Model - Part II : Implementation
In the previous post[6]
,
I summarized several scalable network I/O models in theory. In this article, I will give concrete code to show how to use each model to build a scalable network server. Building scalable server is a challenging task and needs a lot of considerations, we just consider the network I/O model problem here.
When a client request comes in, the server will do some float number calculation, get server system time and then response the client with these information. The code can be found in the
ServeTheClient()
function in
Util.cxx
.
1. Multi-threading
The server consists of two parts:
- One Listening Thread: listen and accept client connection
- Many Worker Threads: one for each client
When new client comes, the Listening Thread accepts it and creates a new worker thread to serve it. The worker thread reads a string data from client, do the processing and send back the output to client.
This is the simplest solution, code can be found here:
Multithreading Network Server
.
2. I/O Multiplexing - BSD Select
In this model, the main thread only init winsock environment, start listening, other worker threads do the real work. Each worker thread handle upto N - 1 client connections(N is the 64 on most BSD compatible systems), one slot is for listening socket.
While using BSD Select to implement network server, you should set the server socket(socket that is used to listen/accept client connections) into non-blocking mode. The reasoning is that, even select() tells that some client connection request had arrived, accept() may block since it's possible that many threads get this notification.
There is a
SELECT_CONN_CTX
data structure for each client connection. It's definitely a state machine style server architecture.
One drawback of current implementation is that the number of threads only increases, never decrease. Worker threads should become less when concurrent client connections drops down.
An alternative design is use some dedicated thread(s) to Listen/Accept client connections and other threads only serve client requests. Since it introduces many shared data among different threads, synchronization mechanisms (such as lock) are needed.
The code -
BSD Select based Network Server
3. I/O Multiplexing - Event Select
It's very similiar to BSD Select model with some small differences:
-
WSAWaitForMultipleEvents
() rather than
select
() is used to wait for network event
- Since the wait function only returns one array index value, we should check all event handles that follows the returned one to ensure fairness.
-
WSAEnumNetworkEvents
() is used to determine the exact network event
- each thread can only serve
WSA_MAXIMUM_WAIT_EVENTS
- 1 client connections
The drawback and possible new architecture is the same as BSD select.
Note
: Socket should be in non-blocking mode to avoid blocking for the same reason as in BSD select model. But
WSAEventSelect
() will put a socket into non-blocking mode, so we don't need to call other function to do this as in BSD select model.
The code -
Event Select based Network Server
4. Overlapped I/O - Event Waiting
In this model, you associate each winsock call with an overlapped data structure, and associate a kernel event with each overlapped data structure. This event is used to get async/overlapped call completion notification.
Core logic:
- The main thread only deal with Init work
- Worker threads do async accept using AcceptEx()
- When client connected, it's served by server in state machine style
- When WSAWaitForMultipleEvents() returns, we should check all following handles to ensure fairness
- When no free slot, a new worker thread will be created to serve more clients.
Since it uses kernel event to get completioin notification, it has the same drawback as "Kernel Event Select" model - each thread can only serve WSA_MAXIMUM_WAIT_EVENTS - 1 client connections.
The code -
Overlapped I/O with Event Waiting based Network Server
5. Overlapped I/O - Callback Routine
In this model, you pass an extra callback routine parameter when issuing overlapped I/O calls.
Since each client connection is represented by a context data structure, which can be accessed in the callback routine, this models seems pretty simple:
- no multiple threading
- no synchronization
- callback routine represents state transition
Core Logic:
- Main thread is a async listen/accept loop
- AcceptEx() sends completion notification using Kernel Event
- Main thread must wait in
alertable state
in order to get overlapped i/o callback routine executed.
The code -
"Overlapped I/O with Callbacking" based Network Server
6. Overlapped I/O - IO Completion Port
This is the
most elegant
solution for a scalable network server:
- The main thread is a
listen/accept thread
, when a client connection arrives, it post a notification to IOCP and let worker thread process it.
- Each
worker thread
deal with each client connection in
state machine
style: using network I/O completion notification to trigger state transition and next operation call.
- Let system to control thread number and scheduling.
You can see from the source code that the logic is very clear and easy to understand. If you are going to write a network server on windows platform, this model is highly recommended.
The code -
"Overlapped I/O with IOCP" based Network Server
Note:
The original version of
CreateIOCompletionPort()
is heavily overloaded on its semantic. So I created two separated function
CreateNewIoCompletionPort
() and
AssociateDeviceWithIoCompletionPort
() to make each one only do one simple function. The definition and implementation can be found in
Util.h
and
Util.cxx
Conclusion
:
Here I listed the implementation of a scalable network server using various network I/O models. In next article, I will do some load test on each server and compare the performance/scalability of each model.
[Reference]
1.
Write Scalable Winsock Application using I/O Completion Port
2.
Writing scalable server applications using I/O Completion Port
3.
Book - Network Programming for Microsoft Windows
4.
Network I/O system call implementation on Linux
5.
Winsock Network I/O Model - Part I : Theory
6.
Scalable I/O Model
0 Comments
scalability
,
network
Blog - Comment List MSDN TechNet
Comments
Loading...
Leave a Comment
Name
Comment
Please add 5 and 8 and type the answer here:
Post