Reproduced in: http://www.cnblogs.com/pen-ink/articles/1834088.html
HANDLE WINAPI CreateIoCompletionPort (
__in HANDLE FileHandle,
__in HANDLE Existingcompletionport,
__IN Ulong_ptr Completionkey,
__in DWORD NumberOfConcurrentThreads
);
/*
This function accomplishes two different tasks: 1, create a completion port object, 2, associate one or more file handles to the I/O completion Port object. A createiocompletionport call can be abstracted into two small functions.
*/
1. Create I/O completion port
HANDLE Createnewcompletionport (DWORD dwnumberofconcurrentthreads)
{
Return (Createnewcompletionport (Invalid_handle_value, NULL, 0, dwnumberofconcurrentthreads));
}
2. Associating the device with the I/O completion port
BOOL Associatedevicewithcompletionport (HANDLE hcompletionport, HANDLE hdevice, DWORD Dwcompletionkey)
{
HANDLE h = createiocompletionport (Hdevice, Hcompletionport, Dwcompletionkey, 0);
return (H = = Hcompletionport);
}
/////////////////////////////////////////////////
IOCPDemo.cpp file Debugging through
#include "WSAInit.h"
#include <stdio.h>
#include <windows.h>
Initializing the Winsock library
Cwsainit Thesock;
#define BUFFER_SIZE 1024
#define OP_READ 1
#define Op_write 2
#define OP_ACCEPT 3
typedef struct _PER_HANDLE_DATA//Per-handle data
{
SOCKET s; Corresponding handle of the sleeve
Sockaddr_in addr; Client-side Address
Char Buf[buffer_size]; Data buffers
int noperationtype; Type of operation
} per_handle_data, *pper_handle_data;
DWORD WINAPI serverthread (LPVOID lpparam)
{
Get completion Port Object handle
HANDLE hcompletion = (HANDLE) Lpparam;
DWORD Dwtrans;
Pper_handle_data Pperhandle;
OVERLAPPED *poverlapped;
while (TRUE)
{
Wait for I/O completion on all the nested words that are associated to this completion port
BOOL BOK =:: GetQueuedCompletionStatus (Hcompletion,
&dwtrans, (pulong_ptr) &pperhandle, &poverlapped, wsa_infinite);
if (!bok)//error occurs on this set of section words
{
:: Closesocket (Pperhandle->s);
:: GlobalFree (Pperhandle);
:: GlobalFree (poverlapped);
Continue
}
if (Dwtrans = = 0 &&//The section Word is closed by the other side
(Pperhandle->noperationtype = = Op_read | | pperhandle->noperationtype = = op_write))
{
:: Closesocket (Pperhandle->s);
:: GlobalFree (Pperhandle);
:: GlobalFree (poverlapped);
continue;
}
Switch (pperhandle->noperationtype)//View what I/O requests are complete through the Noperationtype domain in the PER-I/O data
{
Case Op_read://complete a receive request
{
Pperhandle->buf[dwtrans] = ' + ';
printf (pperhandle-> buf);
Continue delivery receive I/O requests
Wsabuf buf;
Buf.buf = Pperhandle->buf;
Buf.len = buffer_size;
Pperhandle->noperationtype = Op_read;
DWORD nflags = 0;
:: WSARecv (Pperhandle->s, &buf, 1, &dwtrans, &nflags, poverlapped, NULL);
}
Break
Case Op_write://Do not post these types of I/O requests in this example
Case OP_ACCEPT:
Break
}
}
return 0;
}
void Main ()
{
int nport = 4567;
Create a completion Port object, create a worker thread to process the event in the completion port object
HANDLE hcompletion =:: CreateIoCompletionPort (invalid_handle_value, 0, 0, 0);
:: CreateThread (NULL, 0, Serverthread, (LPVOID) hcompletion, 0, 0);
Create a listener section word, bind to a local address, start listening
Socket Slisten =:: Socket (af_inet, sock_stream, 0);
Sockaddr_in si;
si.sin_family = af_inet;
Si.sin_port =:: Ntohs (Nport);
Si.sin_addr. S_un. S_ADDR = Inaddr_any;
:: Bind (Slisten, (sockaddr*) &si, sizeof (SI));
:: Listen (Slisten, 5);
Cyclic processing of incoming connections
while (TRUE)
{
Waiting to accept pending connection requests
Sockaddr_in Saremote;
int nremotelen = sizeof (saremote);
SOCKET snew =:: Accept (Slisten, (sockaddr*) &saremote, &nremotelen);
After accepting the new connection, create a per-handle data for it and associate them to the completion port object.
Pper_handle_data Pperhandle =
(pper_handle_data):: GlobalAlloc (gptr, sizeof (Per_handle_data));
Pperhandle->s = snew;
memcpy (&pperhandle->addr, &saremote, Nremotelen);
Pperhandle->noperationtype = Op_read;
:: CreateIoCompletionPort ((HANDLE) Pperhandle->s, Hcompletion, (ulong_ptr) pperhandle, 0);
Post a Receive request
OVERLAPPED *pol = (OVERLAPPED *):: GlobalAlloc (gptr, sizeof (OVERLAPPED));
Wsabuf buf;
Buf.buf = pperhandle->buf;
Buf.len = buffer_size;
DWORD Dwrecv;
DWORD dwFlags = 0;
:: WSARecv (Pperhandle->s, &buf, 1, &dwrecv, &dwflags, Pol, NULL);
}
}