Click here to Skip to main content
11,706,799 members (48,715 online)
Click here to Skip to main content

Another TCP echo server using IOCP

, 27 Mar 2013 CPOL 40.2K 38
Rate this:
Please Sign up or sign in to vote.
An introduction to writing IOCP network servers

Introduction

This tip shows a very simple non-blocking TCP echo server using Windows Input/Output Completion Ports, capable of handling any number of clients simultaneously.

Background

IOCPs are generally considered the best (some would say the only) way of writing high-performance, highly-scalable network servers in Windows. But there are no simple examples of their use readily available in the internet.
 
This tip intends to fulfill this gap, by providing a very simple C-language IOCP server example. There are no classes to learn, no other Windows API to worry about, no thread stuff to complicate matters, just the two functions relating to IOCPs: CreateIoCompletionPort and GetQueuedCompletionStatus. Also, of course, the usual sockets API are used, in the Winsock asynchronous flavor: AcceptEx, listen, bind, WSARecv and WSASend.

Description

The general flow of control of the echo server is described in the steps below:
1. initialize Winsock (WSAStartup)
2. create the I/O Completion Port (CreateIoCompletionPort)
3. create the listening socket (listen)
4. associate the listening socket with the IOCP (CreateIoCompletionPort)
5. bind the listening socket (bind)
6. start listening (listen)
7. create a pointer to the AcceptEx function (!)
8. start accepting a new connection (asynchronous AcceptEx)
   // the completion status for AcceptEx will be reported through
   // the listen IOCP completion status (see step 4)
9. wait for a completion port status (GetQueuedCompletionStatus)
9.1 if the completion status is for an accept (an AcceptEx has completed)
    9.1.1 "update the context" of the new socket (whatever that is...)
    9.1.2 associate the new socket with the completion port
    9.1.3 start reading from the new socket (asynchronous WSARecv)
    9.1.4 start accepting another connection (asynchronous AcceptEx)
    9.1.5 go to step 9
9.2 if the completion status is for a read (a WSARecv has completed)
    9.2.1 start writing to the socket through which the data arrived,
          echoing back the data (asynchronous WSASend)
    9.2.2 go to step 9
9.3 if the completion status is for a write (a WSASend has completed)
    9.3.1 start reading again from the socket that was used to send the data
          (asynchronous WSARecv)
    9.3.2 go to step 9
 
That's it! Well, there are all those pesky error situations that have to be handled, and there's also some code to track the connections, but all in all, the above pseudo-code sums up most of the program code. One thing to note though is that all operations must be "overlapped" (a kind of asynchronous I/O operation in Windows).
 
Also, there's a small client program (not using IOCPs) that can be used to test the echo server.

Conclusion

IOCPs are easy to use, and the program shipped with this tip intends to show how to do it.
 
You can download the code from here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

José Vitor
Software Developer
Brazil Brazil
I'm a long-time software developer living in Brazil.

I've been developing software for retail and banking automation in C/C++ for many years now. In the old days I even did some COBOL programming, and some assembly for the 8080.

My experience ranges from low level software such as interface code for serial devices for DOS and Windows (bar code scanners, printers, cash dispensers, etc) and goes to writing end user applications for POS terminals and bank ATMs. In between I've done a great deal of TCP/IP programming using the basic Berkeley sockets interface, which is my main interest nowadays.

You may also be interested in...

Comments and Discussions

 
Questionquestion: is it legal to do next start_reading on the same socket that we sent to start_writing before we got write_completed Pin
Avner BenHanoch25-Aug-14 2:43
memberAvner BenHanoch25-Aug-14 2:43 
AnswerRe: question: is it legal to do next start_reading on the same socket that we sent to start_writing before we got write_completed Pin
José Vitor25-Aug-14 3:13
memberJosé Vitor25-Aug-14 3:13 
GeneralRe: question: is it legal to do next start_reading on the same socket that we sent to start_writing before we got write_completed Pin
Avner BenHanoch25-Aug-14 3:50
memberAvner BenHanoch25-Aug-14 3:50 
QuestionBUG ? - you send address of variable on the stack to WSASend (and to WSARecv) Pin
Avner BenHanoch24-Aug-14 21:51
memberAvner BenHanoch24-Aug-14 21:51 
AnswerRe: BUG ? - you send address of variable on the stack to WSASend Pin
José Vitor25-Aug-14 2:32
memberJosé Vitor25-Aug-14 2:32 
GeneralRe: BUG ? - you send address of variable on the stack to WSASend Pin
Avner BenHanoch25-Aug-14 2:53
memberAvner BenHanoch25-Aug-14 2:53 
GeneralRe: BUG ? - you send address of variable on the stack to WSASend Pin
José Vitor25-Aug-14 3:18
memberJosé Vitor25-Aug-14 3:18 
GeneralMy vote of 5 Pin
Member 1102725021-Aug-14 2:41
memberMember 1102725021-Aug-14 2:41 
QuestionHow to download the code? Pin
fjptlqf12-Sep-13 16:13
memberfjptlqf12-Sep-13 16:13 
AnswerRe: How to download the code? Pin
José Vitor12-Sep-13 16:30
memberJosé Vitor12-Sep-13 16:30 
GeneralRe: How to download the code? Pin
Member 1010014827-May-14 1:34
memberMember 1010014827-May-14 1:34 
GeneralRe: How to download the code? Pin
José Vitor27-May-14 1:49
memberJosé Vitor27-May-14 1:49 
QuestionThank You for Putting the Code up for download Pin
Gary Olson27-Mar-13 9:40
memberGary Olson27-Mar-13 9:40 
AnswerRe: Thank You for Putting the Code up for download Pin
José Vitor27-Mar-13 9:59
memberJosé Vitor27-Mar-13 9:59 
GeneralMy vote of 1 Pin
Gary Olson27-Mar-13 4:24
memberGary Olson27-Mar-13 4:24 
GeneralRe: My vote of 1 Pin
José Vitor27-Mar-13 5:54
memberJosé Vitor27-Mar-13 5:54 
SuggestionWin32 Threadpool Wrapper Classes Pin
Rolf Kristensen18-Sep-12 20:31
memberRolf Kristensen18-Sep-12 20:31 
GeneralReason for my vote of 1 Code should NOT be downloadable from... Pin
John Simmons / outlaw programmer10-Nov-11 1:53
mvpJohn Simmons / outlaw programmer10-Nov-11 1:53 
GeneralRe: Reason for my vote of 1Code should NOT be downloadable from... Pin
Member 1102725021-Aug-14 3:16
memberMember 1102725021-Aug-14 3:16 
GeneralReason for my vote of 5 Thanks! Pin
Walt Fair, Jr.27-Sep-11 16:40
subeditorWalt Fair, Jr.27-Sep-11 16:40 
GeneralReason for my vote of 5 Simple and to the point. For quick l... Pin
Ashish Tyagi 4011-Sep-11 7:06
memberAshish Tyagi 4011-Sep-11 7:06 
General"How other threads will be able to accept connection between... Pin
José Vitor12-May-11 14:02
memberJosé Vitor12-May-11 14:02 
"How other threads will be able to accept connection between 9. -> 9.1.5 ?"

This example is not meant to show threading issues, but to be a very simple example of how to use IOCPs.
GeneralRe: It looks like accept (not an EX version) in the separate thr... Pin
Pavel Sokolov13-May-11 13:54
memberPavel Sokolov13-May-11 13:54 
GeneralHow other threads will be able to accept connection between ... Pin
Pavel Sokolov12-May-11 12:01
memberPavel Sokolov12-May-11 12:01 
GeneralRe: How other threads will be able to accept connection between ... Pin
Tutankhamen11-Jun-13 17:27
memberTutankhamen11-Jun-13 17:27 
GeneralReason for my vote of 5 very nice Pin
mier2-Nov-10 5:07
membermier2-Nov-10 5:07 
GeneralHello, About "Black Magic Code". You do not need to call in... Pin
Chavenay31-Oct-10 7:12
memberChavenay31-Oct-10 7:12 
GeneralReason for my vote of 5 simple and efficient! Pin
Member 374556515-Aug-10 8:15
memberMember 374556515-Aug-10 8:15 
Generalhello, download link does not work Pin
Member 794381421-May-11 20:13
memberMember 794381421-May-11 20:13 
GeneralRe: hello, download link does not work Pin
José Vitor22-May-11 3:45
memberJosé Vitor22-May-11 3:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150819.1 | Last Updated 27 Mar 2013
Article Copyright 2010 by José Vitor
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid