#include"iocp.h"
CIocp::CIocp(){
m_nWorkerThread = new HANDLE[16];
m_pkey = new COMPLETIONKEY;
}
void CIocp::main_process(){
if(0!=wrap_CreateNewIoCompletionPort(&m_hIOCompletionPort))
return;
int m_nThreads = 2 * wrap_GetProcessorsNumber();
for(int i=0;i<m_nThreads;i++){
m_nWorkerThread[i]=(HANDLE)_beginthreadex(NULL,0,_WorkerThreads,this,0,0);
}
if(wrap_WSAStartup()!=0)
return;
m_sockListen = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
m_pkey->s = m_sockListen;
CreateIoCompletionPort((HANDLE)m_sockListen,m_hIOCompletionPort,(ULONG_PTR)m_pkey,0);
addrinfo *serverinfo,*p;
if(0!=wrap_getaddrinfo(NULL,PORT,&serverinfo))
return;
for(p=serverinfo;p!=NULL;p=p->ai_next)
if(SOCKET_ERROR!=bind(m_sockListen,serverinfo->ai_addr,serverinfo->ai_addrlen))
break;
else err_no("bind");
freeaddrinfo(serverinfo);
if(p==NULL) err_no("all bind");
listen(m_sockListen,5);
GUID guidAcceptEx = WSAID_ACCEPTEX;
DWORD dwBytes = 0;
if(WSAIoctl(m_sockListen,SIO_GET_EXTENSION_FUNCTION_POINTER,
&guidAcceptEx,sizeof(guidAcceptEx),&m_lpfnAcceptEx,sizeof(m_lpfnAcceptEx),
&dwBytes,NULL,NULL)!=0){
err_no("wsaioctl");
}
int i=200;
while(i--){
IO_OPERATION_DATA* pcompletionkey = new IO_OPERATION_DATA;
ASY_accept(pcompletionkey);
}
Sleep(100000);
for(int i =0;i<m_nThreads;i++){
IO_OPERATION_DATA* pIOData = new IO_OPERATION_DATA;
pIOData->t_info=0x00;
PostQueuedCompletionStatus(m_hIOCompletionPort,-1,(ULONG_PTR)m_pkey,&pIOData->overlapped);
}
WaitForMultipleObjects(m_nThreads,m_nWorkerThread,true,INFINITE);
closesocket(m_sockListen);
CloseHandle(m_hIOCompletionPort);
}
unsigned int __stdcall CIocp::_WorkerThreads(PVOID pm){
CIocp* CI =(CIocp*)pm;
PCOMPLETIONKEY lpContext = NULL;
LPOVERLAPPED pOverlapped = NULL;
DWORD dwBytesTransfered = -1;
IO_OPERATION_DATA *iod = NULL;
for(;;){
BOOL bReturn = GetQueuedCompletionStatus(CI->GetIoCompletionPort(),&dwBytesTransfered,(PULONG_PTR)&lpContext,&pOverlapped,INFINITE);
iod = (IO_OPERATION_DATA*)pOverlapped;
switch(iod->t_info){
case ACCEPT:{
CI->ASY_recv(iod->s,iod);
}
case READ:
closesocket(iod->s);
if(!WSACloseEvent(iod->overlapped.hEvent))
err_no("close event");
CI->ASY_accept(iod);
break;
default:
printf("break\n");
delete iod;
return 0;
break;
}
}
return 0;
}
void CIocp::ASY_send(SOCKET s,IO_OPERATION_DATA* p){
p->t_info = WRITE;
sprintf(p->buffer,"hallo");
p->dataBuf.buf = p->buffer;
p->dataBuf.len = sizeof(p->buffer);
WSAResetEvent(p->overlapped.hEvent);
DWORD flags=0;
DWORD size = sizeof(p->dataBuf);
if(0!=WSASend(p->s,&p->dataBuf,1,&size,flags,&p->overlapped,NULL)){
int err;
if((err=WSAGetLastError())==WSA_IO_PENDING)
printf("send pending\n");
else printf("send:%d\n",err);
}
else
{
printf("sended\n\n");
closesocket(p->s);
ASY_accept(p);
}
}
void CIocp::ASY_recv(SOCKET s,IO_OPERATION_DATA* p){
p->t_info = READ;
p->dataBuf.buf = p->buffer;
p->dataBuf.len = sizeof(p->buffer);
if(!WSAResetEvent(p->overlapped.hEvent))
err_no("reset event");
DWORD flags=0;
WSARecv(p->s,&p->dataBuf,1,NULL,&flags,&p->overlapped,NULL);
if(WSAGetLastError()!=WSA_IO_PENDING)
err_no("recv");
}
void CIocp::ASY_accept(IO_OPERATION_DATA* p){
p->s = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
p->t_info = ACCEPT;
DWORD dwBytes = 0;
memset(&p->overlapped, 0, sizeof (p->overlapped));
p->overlapped.hEvent = WSACreateEvent();
if(p->overlapped.hEvent == WSA_INVALID_EVENT)
err_no("create event");
if(0==m_lpfnAcceptEx(m_sockListen,p->s,p->buffer,BUFFER_SIZE-(sizeof(SOCKADDR_IN)+16)*2,sizeof(SOCKADDR_IN)+16,sizeof(SOCKADDR_IN)+16,&dwBytes,&p->overlapped)){
if(WSAGetLastError()==WSA_IO_PENDING)
printf("pending……\n");
printf_time();
}else
printf("notpending***\n");
}
#pragma once
#pragma warning(disable:4996)
#include"wrap_sock.h"
#include"err_no.h"
#include<iostream>
#include<process.h>
#include <mswsock.h>
#define PORT "3490"
#define OPERATION_TYPE int
#define WRITE 0x1
#define READ 0x2
#define ACCEPT 0x3
#define BUFFER_SIZE 512
typedef struct _completionKey
{
SOCKET s;
SOCKADDR_IN clientAddr;
}COMPLETIONKEY,*PCOMPLETIONKEY;
typedef struct _io_operation_data
{
OVERLAPPED overlapped;
WSABUF dataBuf;
CHAR buffer[BUFFER_SIZE];
int t_info;
SOCKET s;
}IO_OPERATION_DATA;
class CIocp{
public:
CIocp();
void main_process();
void ASY_send(SOCKET s,IO_OPERATION_DATA* p);
void ASY_recv(SOCKET s,IO_OPERATION_DATA* p);
void ASY_accept(IO_OPERATION_DATA* pcompletionkey);
LPFN_ACCEPTEX GetAcceptFunc()const{return m_lpfnAcceptEx;}
HANDLE GetIoCompletionPort()const{return m_hIOCompletionPort;}
private:
PHANDLE m_nWorkerThread;
HANDLE m_hIOCompletionPort;
LPFN_ACCEPTEX m_lpfnAcceptEx;
PCOMPLETIONKEY m_pkey;
SOCKET m_sockListen;
static unsigned int __stdcall _WorkerThreads(PVOID pm);
};
#include<WinSock2.h>
#include<WS2tcpip.h>
#include"err_no.h"
#pragma comment(lib,"ws2_32.lib")
int wrap_CreateNewIoCompletionPort(HANDLE* iocp);
int wrap_GetProcessorsNumber();
int wrap_WSAStartup();
int wrap_getaddrinfo(const char* servername,const char* port,PADDRINFOA* m_serverinfo);
int wrap_socket(SOCKET* sock,int af,int type,int protocol);
int wrap_connect(SOCKET serverfd,const sockaddr* addr,int namelen);
int wrap_recv(SOCKET serverfd,char* recvbuf,int bufsize,int flag);
int wrap_send(SOCKET serverfd,const char* recvbuf,int bufsize,int flag);
#include"wrap_sock.h"
int wrap_CreateNewIoCompletionPort(HANDLE* iocp){
*iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
if(*iocp==0){
err_no("create IOCP");
return -1;
}
else return 0;
}
int wrap_GetProcessorsNumber(){
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwNumberOfProcessors;
}
int wrap_WSAStartup(){
WSAData m_wd;
if(0!=WSAStartup(MAKEWORD(1,1),&m_wd)){
err_no("WSAStartup");
return -1;
}
return 0;
}
int wrap_getaddrinfo(const char* servername,const char* port,PADDRINFOA* serverinfo){
addrinfo hints;
memset(&hints,0,sizeof(addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if(0!=getaddrinfo(servername,port,&hints,serverinfo)){
err_no("getaddrinfo failed");
return -1;
}
return 0;
}
int wrap_recv(SOCKET serverfd,char* recvbuf,int bufsize,int flag){
if(-1==recv(serverfd,recvbuf,bufsize,flag)){
err_no("recv failed");
closesocket(serverfd);
return -1;
}
return 0;
}
int wrap_send(SOCKET serverfd,const char* recvbuf,int bufsize,int flag){
if(-1==send(serverfd,recvbuf,bufsize,flag)){
err_no("send failed");
closesocket(serverfd);
return -1;
}
return 0;
}
int wrap_connect(SOCKET serverfd,const sockaddr* addr,int namelen){
if(0!=connect(serverfd,addr,namelen)){
err_no("connect failed");
closesocket(serverfd);
return -1;
}
return 0;
}
int wrap_socket(SOCKET* sock,int af,int type,int protocol){
SOCKET tmp;
if((tmp = socket(af,type,protocol))==-1){
err_no("socket failed");
return -1;
}
*sock = tmp;
return 0;
}