// 完成端口.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Winsock2.h"
#pragma comment(lib,"WS2_32.lib")
//完成键的结构体
typedef struct _COMPLETIONKEY
{
SOCKET sock;
int ErrorCode;
}COMPLETIONKEY,*PCOMPLETIONKEY;
//自定义OverLapped结构体
typedef struct _MYOVERLAPPED
{
WSAOVERLAPPED stcOvlapped;
WSABUF WsaBuf;
char OverBuf[1024];
int nOperType;
}MYOVERLAPPED,*PMYOVERLAPPED;
DWORD ThreadProc(LPVOID prama)
{
HANDLE hPort = (HANDLE)prama;
DWORD dwSize = 0;
PCOMPLETIONKEY pCompletionKey = NULL;
PMYOVERLAPPED pOverLapped = NULL;
BOOL bResult = FALSE;
while (true)
{
bResult = GetQueuedCompletionStatus(
hPort,
&dwSize,
(PULONG_PTR)&pCompletionKey,
(LPOVERLAPPED*)&pOverLapped,
-1);
if (bResult == FALSE)
{
//处理错误
}
if (pCompletionKey->ErrorCode == -1)
{
PMYOVERLAPPED pOverlapped = new MYOVERLAPPED;
memset(pOverlapped,0,sizeof(MYOVERLAPPED));
//投递一个退出通知
PostQueuedCompletionStatus(hPort,0,
(ULONG_PTR)pCompletionKey,
(LPOVERLAPPED)pOverlapped);
ExitThread(0);
}
if (pOverLapped != NULL)
{
if (pOverLapped->nOperType == 1)
{
printf("%s",pOverLapped->OverBuf);
//消耗掉了之前的接受操作,
//再投递一个接收数据的操作
DWORD dwSize = 0;
WSABUF WsaBuf;
WsaBuf.buf = pOverLapped->OverBuf;
WsaBuf.len = 1024;
WSARecv(
pCompletionKey->sock,
&WsaBuf,
1,
&dwSize,
0,(LPWSAOVERLAPPED)pOverLapped,NULL);
}
}
}
}
void Init()
{
WSADATA stcWsaData = {0};
WSAStartup(MAKEWORD(2,2),&stcWsaData);
}
SOCKET InitTcp()
{
SOCKET sock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,
WSA_FLAG_OVERLAPPED);
if (sock == INVALID_SOCKET)
{
return INVALID_SOCKET;
}
sockaddr_in BindAddr;
BindAddr.sin_family = AF_INET;
BindAddr.sin_port = htons(1234);
BindAddr.sin_addr.S_un.S_addr =
inet_addr("192.168.199.119");
if (SOCKET_ERROR == bind(
sock,(sockaddr*)&BindAddr,
sizeof(sockaddr_in)))
{
return INVALID_SOCKET;
}
if (SOCKET_ERROR == listen(sock,4))
{
closesocket(sock);
return INVALID_SOCKET;
}
return sock;
}
int _tmain(int argc, _TCHAR* argv[])
{
//1 初始化Socket和完成端口
Init();
SOCKET sock = InitTcp();
HANDLE hPort = CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
0,
0,
4
);
//2 获取CPU核心数量,并开启工作线程
SYSTEM_INFO stcSystemInfo = {0};
GetSystemInfo(&stcSystemInfo);
for (DWORD i =0;i<stcSystemInfo.dwNumberOfProcessors*2;i++)
{
CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)hPort,0,0);
}
while (TRUE)
{
sockaddr_in ClientAddr;
int nAddrSize = sizeof(sockaddr_in);
SOCKET Clientsock = accept(
sock,
(sockaddr*)&ClientAddr,
&nAddrSize);
//将客户端Socket和完成端口绑定
PCOMPLETIONKEY pClientComKey= new COMPLETIONKEY;
pClientComKey->sock = Clientsock;
CreateIoCompletionPort((HANDLE)Clientsock,hPort,
(ULONG_PTR)pClientComKey,0);
DWORD dwSize = 0;
DWORD dwRubbish = 0;
PMYOVERLAPPED pOverlapped = new MYOVERLAPPED;
//将OverLapped结构初始化为0
memset(pOverlapped,0,sizeof(MYOVERLAPPED));
pOverlapped->nOperType = 1;
pOverlapped->WsaBuf.buf = pOverlapped->OverBuf;
pOverlapped->WsaBuf.len = 1024;
//投递一个接收操作,并不能真正的获取到数据
WSARecv(
pClientComKey->sock,
&(pOverlapped->WsaBuf),
1,
&dwSize,
&dwRubbish,(LPWSAOVERLAPPED)pOverlapped,NULL);
}
return 0;
}
IOCP原理
最新推荐文章于 2025-02-08 14:53:33 发布