#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...