#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include <process.h>
#include<Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define BUFFER_SIZE 1024
#define RET_FAIL 0
#define RET_SUCCESS 1
typedef struct SOCKET_DATA
{
SOCKET s;
sockaddr_in addr;
}*P_SOCKET_DATA;
enum TYPE
{
TYPE_READ,
TYPE_WRITE,
};
typedef struct OVERLAPPED_EX:public OVERLAPPED
{
int nType;
char szBuf[BUFFER_SIZE];
OVERLAPPED_EX()
{
ZeroMemory(this,sizeof(OVERLAPPED_EX));
}
}*P_OVERLAPPED_EX;
UINT WINAPI WorkThread(PVOID pLparam);
int _tmain(int argc, _TCHAR* argv[])
{
//加载协议族
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
cout<<"WSAStartup 错误"<<endl;
return RET_FAIL;
}
//创建完成端口
HANDLE hdIOCompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
if(hdIOCompletionPort==NULL)
{
cout<<"CreateIoCompletionPort 创建完成端口错误"<<endl;
return RET_FAIL;
}
//创建线程
SYSTEM_INFO si;
GetSystemInfo(&si);
int nThreadNum=si.dwNumberOfProcessors*2;
for(int i=0;i<nThreadNum;++i)
{
_beginthreadex(NULL,0,WorkThread,(PVOID)hdIOCompletionPort,0,NULL);
}
//创建监听套接字并绑定,监听
SOCKET sListen=socket(AF_INET,SOCK_STREAM,0);
if(sListen==INVALID_SOCKET)
{
cout<<"sListen 错误"<<endl;
return RET_FAIL;
}
int nPort=5050;
sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=INADDR_ANY;
addr.sin_port=htons(nPort);
if(bind(sListen,(sockaddr*)&addr,sizeof(sockaddr_in))==SOCKET_ERROR)
{
cout<<"bind 错误"<<endl;
return RET_FAIL;
}
listen(sListen,100);
//主循环
while(TRUE)
{
sockaddr_in recvAddr;
int nAddrSize=sizeof(sockaddr_in);
SOCKET recvSock=accept(sListen,(sockaddr*)&recvAddr,&nAddrSize);
if(recvSock==INVALID_SOCKET)
{
cout<<"accept 错误"<<endl;
return RET_FAIL;
}
P_SOCKET_DATA psd=new SOCKET_DATA;
memcpy(&(psd->addr),&recvAddr,nAddrSize);
psd->s=recvSock;
if(CreateIoCompletionPort((HANDLE)recvSock,hdIOCompletionPort,(ULONG_PTR)psd,0)==NULL)
{
cout<<"CreateIoCompletionPort 绑定完成端口错误"<<endl;
return RET_FAIL;
}
P_OVERLAPPED_EX poe=new OVERLAPPED_EX;
poe->nType=TYPE_READ;
WSABUF wb;
wb.buf=poe->szBuf;
wb.len=BUFFER_SIZE;
DWORD dw1=0;
DWORD dw2=0;
if(WSARecv(recvSock,&wb,1,&dw1,&dw2,poe,NULL)==SOCKET_ERROR)
{
switch(WSAGetLastError())
{
case WSA_IO_PENDING:
continue;
break;
}
cout<<"WSARecv 错误"<<endl;
return RET_FAIL;
}
}
WSACleanup();
return 0;
};
UINT WINAPI WorkThread(PVOID pLparam)
{
HANDLE hdIOCompletionPort=(HANDLE)pLparam;
while(true)
{
DWORD dwSize=0;
P_SOCKET_DATA psd=0;
P_OVERLAPPED_EX poe=0;
BOOL bRet=GetQueuedCompletionStatus(
hdIOCompletionPort,&dwSize,(PULONG_PTR)&psd,(LPOVERLAPPED*)&poe,WSA_INFINITE);
if(bRet==0)
{
cout<<"bRet=0"<<endl;
closesocket(psd->s);
delete psd;
delete poe;
continue;
}
if(dwSize==0&&(poe->nType==TYPE_READ||poe->nType==TYPE_WRITE))
{
cout<<"客户端套接字已经关闭"<<endl;
closesocket(psd->s);
delete psd;
delete poe;
continue;
}
switch(poe->nType)
{
case TYPE_READ:
{
(poe->szBuf)[BUFFER_SIZE-1]=0;
cout<<poe->szBuf<<endl;
ZeroMemory(poe,sizeof(OVERLAPPED_EX));
poe->nType=TYPE_READ;
WSABUF wb;
wb.buf=poe->szBuf;
wb.len=BUFFER_SIZE;
DWORD dw1=0;
DWORD dw2=0;
if(WSARecv(psd->s,&wb,1,&dw1,&dw2,poe,NULL)==SOCKET_ERROR)
{
cout<<"线程WSARecv 错误"<<endl;
continue;
}
}
break;
}
}
return 0;
};
IOCP基础示例
最新推荐文章于 2023-03-24 20:10:02 发布