#include <WS2tcpip.h>
#include <windows.h>
#include <mswsock.h>
#include <process.h>
#include <stdio.h>
#include <exception>
using std::exception;
#pragma comment(lib, "ws2_32")
#pragma comment(lib, "mswsock")
enum EIoType
{
eIoType_Send,
eIoType_Recv
};
struct SIoContext
{
SIoContext() : sock(INVALID_SOCKET), eIoType(eIoType_Send)
{
memset(&OverLapped, 0, sizeof OverLapped);
wsBuff.buf = buff;
wsBuff.len = sizeof buff;
}
OVERLAPPED OverLapped;
SOCKET sock;
WSABUF wsBuff;
char buff[65536];
EIoType eIoType;
};
void InitNetEnvironment()
{
WSAData wsaData;
if (0 == WSAStartup(MAKEWORD(2, 2), &wsaData)
&& wsaData.wVersion == 0x202)
{
return;
}
throw("网络初始化失败");
}
unsigned int __stdcall ThdDeal(void* pVoid);
int main()
{
InitNetEnvironment();
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == sockSrv)
{
throw(exception("监听套接字初始化失败"));
}
sockaddr_in sockAddr = {};
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(8000);
if (1 != inet_pton(AF_INET, "192.168.0.51",
&sockAddr.sin_addr.s_addr))
{
throw(exception("监听套接字地址初始化失败"));
}
if (SOCKET_ERROR == bind(sockSrv,
reinterpret_cast<sockaddr*>(&sockAddr), sizeof sockaddr))
{
throw(exception("监听套接字bind失败"));
}
if (SOCKET_ERROR == listen(sockSrv, 100))
{
throw(exception("监听套接字listen失败"));
}
HANDLE hIoCmp =
CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (NULL == hIoCmp)
{
throw(exception("创建IO完成端口失败"));
}
for (int i = 0; i < 4; ++i)
{
CloseHandle(reinterpret_cast<HANDLE>
(_beginthreadex(nullptr, 0, ThdDeal, hIoCmp, 0, nullptr)));
}
while (true)
{
SIoContext* pIoContext = new SIoContext();
pIoContext->sock = accept(sockSrv, nullptr, nullptr);
if (INVALID_SOCKET == pIoContext->sock)
{
throw(exception("创建套接字失败"));
}
CreateIoCompletionPort(reinterpret_cast<HANDLE>(pIoContext->sock),
hIoCmp, reinterpret_cast<ULONG_PTR>(pIoContext), 0);
DWORD nFlag = 0;
pIoContext->eIoType = eIoType_Recv;
WSARecv(pIoContext->sock, &pIoContext->wsBuff, 1, nullptr, &nFlag,
&pIoContext->OverLapped, NULL);
}
return 0;
}
unsigned int __stdcall ThdDeal(void* pVoid)
{
HANDLE hIoCmp = static_cast<HANDLE>(pVoid);
DWORD nSize = 0;
ULONG_PTR nCmpKey = 0;
LPOVERLAPPED pOverLapped = nullptr;
while (true)
{
if (GetQueuedCompletionStatus(hIoCmp, &nSize, &nCmpKey,
&pOverLapped, INFINITE))
{
SIoContext* pIoContext =
reinterpret_cast<SIoContext*>(nCmpKey);
if (eIoType_Recv == pIoContext->eIoType)
{
pIoContext->eIoType = eIoType_Send;
pIoContext->wsBuff.len = static_cast<unsigned long>
(pIoContext->OverLapped.InternalHigh);
if (pIoContext->wsBuff.len)
{
WSASend(pIoContext->sock, &pIoContext->wsBuff, 1,
nullptr, 0, &pIoContext->OverLapped, nullptr);
}
else
{
closesocket(pIoContext->sock);
delete pIoContext;
}
}
else
{
printf("Same Data Send to Client, Continue To Recv\n");
DWORD nFlag = 0;
pIoContext->eIoType = eIoType_Recv;
pIoContext->wsBuff.len = sizeof pIoContext->buff;
WSARecv(pIoContext->sock, &pIoContext->wsBuff, 1, nullptr,
&nFlag, &pIoContext->OverLapped, NULL);
}
}
}
return 0;
}
IO完成端口
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 公司内部有一个网站,网站包含邮箱密码找回功能。很常用的一个功能,邮箱的 EmailHelper 在网上也是一找一大...
- 开篇之前先放上本次讲的IOCP project github地址:这里 。这个project中包含了IOCP和se...