当前位置: 首页 > news >正文

.net 导航网站模板最新军事消息

.net 导航网站模板,最新军事消息,自然资源网站官网,仪器网站模板说明 使用IO完成端口实现简单回显服务器,因为是测试用的,所以代码很粗糙。 提醒 使用的是ReadFile、WriteFile来实现Overlapped IO,正式场合应该用WSARecv、WSASend,原因:来自《Windows网络编程技术》 8.2.5节 在这里…

说明

使用IO完成端口实现简单回显服务器,因为是测试用的,所以代码很粗糙。

  • 提醒
    使用的是ReadFile、WriteFile来实现Overlapped IO,正式场合应该用WSARecv、WSASend,原因:来自《Windows网络编程技术》 8.2.5节
    在这里插入图片描述

  • 技术点记录下
    io以同步方式立马完成时,系统也会将此通知投递到io完成端口通知列表中,这么做的原因是方便用户编码。
    SetFileCompletionNotificationModes传入FILE_SKIP_COMPLETION_PORT_ON_SUCCESS告诉系统,io以同步方式立马完成时,不要
    将此事件投递到IO完成端口列表中。

    参看《Windows核心编程》第10章 10.5.4
    在这里插入图片描述
    在这里插入图片描述

代码

#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <set>
#include <memory>
#include <process.h>#pragma comment(lib, "Ws2_32.lib")class MyOverlapped
{
public:MyOverlapped():m_bIsRead(false){memset(&m_Overlapped, 0, sizeof(OVERLAPPED));}OVERLAPPED m_Overlapped;bool m_bIsRead;
};struct ClientSocketItem
{ClientSocketItem(){hSocket = NULL;memset(szRecv, 0, sizeof(szRecv));nRecvSize = 0;bFinished = false;nWriteOffset = 0;readOverlapped.m_bIsRead = true;writeOverlapped.m_bIsRead = false;}SOCKET hSocket;std::string strIp;MyOverlapped readOverlapped;char szRecv[1024];unsigned int nRecvSize;MyOverlapped writeOverlapped;unsigned int nWriteOffset = 0;bool bFinished;
};
std::set<ClientSocketItem*> g_Clients;HANDLE g_hIoCompletionPort = NULL;bool do_read(ClientSocketItem* pClient)
{if (!pClient){return false;}char c = 0; //测试用,每次只读一个字符DWORD dwReadBytes;if (::ReadFile((HANDLE)(pClient->hSocket), &(pClient->szRecv[pClient->nRecvSize]),1, &dwReadBytes, &(pClient->readOverlapped.m_Overlapped))){return true;}DWORD dwError = ::GetLastError();if (ERROR_IO_PENDING == dwError){return true;}std::cerr << "read failed with error " << dwError << std::endl;return false;
}bool do_write(ClientSocketItem* pClient)
{if (!pClient){return false;}//测试用,每次只发送一个字符DWORD dwWriteBytes = 0;if (::WriteFile((HANDLE)(pClient->hSocket), &(pClient->szRecv[pClient->nWriteOffset]),1, &dwWriteBytes, &(pClient->writeOverlapped.m_Overlapped))){return true;}DWORD dwError = ::GetLastError();if (ERROR_IO_PENDING == dwError){return true;}std::cerr << "write failed with error " << dwError << std::endl;return false;
}bool do_accept(SOCKET hListenSocket)
{sockaddr_in mPeerAddr = { 0 };int nAddrLen = sizeof(sockaddr);SOCKET hClientSocket = accept(hListenSocket, (sockaddr*)(&mPeerAddr), &nAddrLen);if (INVALID_SOCKET == hClientSocket){std::cout << "accept failed with error "<< WSAGetLastError() << std::endl;return false;}else{unsigned long nNoBlock = 0;ioctlsocket(hClientSocket, FIONBIO, &nNoBlock);std::string strIpAddr = inet_ntoa(mPeerAddr.sin_addr);std::cout << "accept success, peer ip is " << strIpAddr.c_str() << std::endl;auto pClient = new ClientSocketItem();pClient->hSocket = hClientSocket;pClient->strIp = strIpAddr;g_Clients.insert(pClient);//附加到IO完成端口上if (g_hIoCompletionPort != ::CreateIoCompletionPort(HANDLE(pClient->hSocket),g_hIoCompletionPort, ULONG_PTR(pClient), 0)){std::cerr << "attach socket to io completion port failed with error"<< ::GetLastError() << std::endl;closesocket(hClientSocket);return false;}//触发读取if (!do_read(pClient)){closesocket(pClient->hSocket);g_Clients.erase(pClient);std::cerr << "do_read failed, close client" << std::endl;}return true;}
}//读写线程函数
unsigned __stdcall ReadWriteThreadFun(void* pParam)
{DWORD dwTransferBytes = 0;ULONG_PTR nCompleteKey = 0;LPOVERLAPPED lpOverlapped = NULL;while (::GetQueuedCompletionStatus(g_hIoCompletionPort, &dwTransferBytes,&nCompleteKey, &lpOverlapped, INFINITE)){if (nCompleteKey == UINT_MAX){std::cout << "user require quit" << std::endl;break;}if (!lpOverlapped){std::cerr << "lpOverlapped is null" << std::endl;break;}ClientSocketItem* pClient = (ClientSocketItem*)nCompleteKey;MyOverlapped* pMyOverlapped = CONTAINING_RECORD(lpOverlapped, MyOverlapped, m_Overlapped);if (!pMyOverlapped || !pClient){std::cerr << "pMyOverlapped or pClient is null" << std::endl;break;}if (pMyOverlapped->m_bIsRead)//read finished notify{char c = pClient->szRecv[pClient->nRecvSize];pClient->nRecvSize += dwTransferBytes;std::cout << "read one char: " << c << std::endl;if (c == '\n'){std::cout << "read finished, start to write" << std::endl;if (!do_write(pClient)){std::cerr << "do_write failed, close socket" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}}else{std::cout << "next char read" << std::endl;if (!do_read(pClient)){std::cerr << "do_read failed, close socket" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}}}else //write finished notify{char c = pClient->szRecv[pClient->nWriteOffset];std::cout << "send one char: " << c << std::endl;pClient->nWriteOffset += dwTransferBytes;if (pClient->nWriteOffset == pClient->nRecvSize){std::cout << "send finished, close client(" << pClient->strIp.c_str()<< ")" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}else{std::cout << "next send" << std::endl;if (!do_write(pClient)){std::cerr << "do_write failed, close socket" << std::endl;closesocket(pClient->hSocket);g_Clients.erase(pClient);}}}}std::cout << "thread quit" << std::endl;return 0;
}int main(int argc, char* argv)
{WORD wVersionRequested = MAKEWORD(2, 2);WSADATA wsaData = { 0 };int err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return -1;}if (LOBYTE(wsaData.wVersion) != 2 ||HIBYTE(wsaData.wVersion) != 2){WSACleanup();return -1;}SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == hListenSocket){std::cerr << "create socket failed with error " << WSAGetLastError()<< std::endl;return -1;}sockaddr_in mSockAddrIn = { 0 };mSockAddrIn.sin_family = AF_INET;mSockAddrIn.sin_port = htons((u_short)8878);mSockAddrIn.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");if (SOCKET_ERROR == bind(hListenSocket, (sockaddr*)(&mSockAddrIn),sizeof(sockaddr))){std::cerr << "bind failed with error " << WSAGetLastError() << std::endl;return -1;}if (SOCKET_ERROR == listen(hListenSocket, SOMAXCONN)){std::cerr << "listen failed with error " << WSAGetLastError() << std::endl;return -1;}//创建完成端口g_hIoCompletionPort = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);if (NULL == g_hIoCompletionPort){std::cerr << "create io completion port failed with error " << ::GetLastError() << std::endl;return -1;}//创建一堆服务线程for (int i = 0; i < 4; ++i){_beginthreadex(0, 0, ReadWriteThreadFun, 0, 0, nullptr);}while (true){if (!do_accept(hListenSocket)){break;}}::PostQueuedCompletionStatus(g_hIoCompletionPort, 0, UINT_MAX, nullptr);Sleep(2000); return 0;
}

文章转载自:
http://chillily.mdwb.cn
http://toynbeean.mdwb.cn
http://blastula.mdwb.cn
http://irbm.mdwb.cn
http://brochure.mdwb.cn
http://locally.mdwb.cn
http://suspicious.mdwb.cn
http://hangman.mdwb.cn
http://bagnio.mdwb.cn
http://almsfolk.mdwb.cn
http://candler.mdwb.cn
http://bipinnate.mdwb.cn
http://treasurership.mdwb.cn
http://burial.mdwb.cn
http://peter.mdwb.cn
http://pauper.mdwb.cn
http://dedans.mdwb.cn
http://crabby.mdwb.cn
http://hyperexcitability.mdwb.cn
http://froglet.mdwb.cn
http://peccatophobia.mdwb.cn
http://yum.mdwb.cn
http://beverley.mdwb.cn
http://quantity.mdwb.cn
http://grudging.mdwb.cn
http://yugoslavic.mdwb.cn
http://livelily.mdwb.cn
http://optimum.mdwb.cn
http://benzedrine.mdwb.cn
http://antileukemic.mdwb.cn
http://vectorscope.mdwb.cn
http://lunatic.mdwb.cn
http://worried.mdwb.cn
http://operose.mdwb.cn
http://universally.mdwb.cn
http://polysemy.mdwb.cn
http://megarad.mdwb.cn
http://spermatological.mdwb.cn
http://cutwater.mdwb.cn
http://databank.mdwb.cn
http://spiritedness.mdwb.cn
http://tortoise.mdwb.cn
http://flameout.mdwb.cn
http://demonize.mdwb.cn
http://appurtenances.mdwb.cn
http://transferror.mdwb.cn
http://anglofrisian.mdwb.cn
http://archontic.mdwb.cn
http://scintiscanner.mdwb.cn
http://ambsace.mdwb.cn
http://impracticability.mdwb.cn
http://pyrogallate.mdwb.cn
http://housetop.mdwb.cn
http://chimerical.mdwb.cn
http://voraciously.mdwb.cn
http://recursive.mdwb.cn
http://gooney.mdwb.cn
http://quadrilingual.mdwb.cn
http://electrotonic.mdwb.cn
http://interbedded.mdwb.cn
http://matilda.mdwb.cn
http://cerastium.mdwb.cn
http://konak.mdwb.cn
http://vat.mdwb.cn
http://vivisect.mdwb.cn
http://anodic.mdwb.cn
http://appropriate.mdwb.cn
http://homomorphism.mdwb.cn
http://rhoda.mdwb.cn
http://cathead.mdwb.cn
http://sepiolite.mdwb.cn
http://intensive.mdwb.cn
http://lotusland.mdwb.cn
http://interoffice.mdwb.cn
http://beaded.mdwb.cn
http://contradance.mdwb.cn
http://revoke.mdwb.cn
http://scamper.mdwb.cn
http://gravlax.mdwb.cn
http://lacunary.mdwb.cn
http://antonym.mdwb.cn
http://malajustment.mdwb.cn
http://robust.mdwb.cn
http://verus.mdwb.cn
http://scapegrace.mdwb.cn
http://reformed.mdwb.cn
http://spadable.mdwb.cn
http://dinette.mdwb.cn
http://rejectant.mdwb.cn
http://circumambience.mdwb.cn
http://harmonometer.mdwb.cn
http://photomural.mdwb.cn
http://combination.mdwb.cn
http://dissymmetry.mdwb.cn
http://busy.mdwb.cn
http://undistinguished.mdwb.cn
http://hydrocephaloid.mdwb.cn
http://encephalous.mdwb.cn
http://countrymen.mdwb.cn
http://lab.mdwb.cn
http://www.15wanjia.com/news/87105.html

相关文章:

  • 峰峰做网站b站免费版入口
  • 做健身俱乐部网站的目的和意义网络推广渠道
  • 小程序开发定制北京公司百度seo关键词外包
  • php网站开发方案最近发生的热点新闻事件
  • 做网站是靠什么赚钱搜狗搜索网
  • 九江县建设规划局网站长尾词seo排名
  • ipad做网站服务器奶茶推广软文200字
  • 深圳有哪些网站建设公司网络推广方案七步法
  • 武汉高端做网站网站搜什么关键词好
  • 珠海建设改革有哪些网站单页网站模板
  • 正规网站建设排行专业网站制作网站公司
  • 公司网站建设优点优化网站视频
  • 网站建设平台招商跟我学seo从入门到精通
  • 360做网站吗成都网站快速开发
  • 广州新塘做网站西安 做网站
  • 东莞网站建设服务商google官网浏览器
  • 建设企业学习网站百度上传自己个人简介
  • 用brackets做网站百度有人工客服吗
  • 网站建设收费标准服务ip域名查询
  • 网站做哪些主题比较容易做新东方留学机构官网
  • 去哪找做塑料的网站怎样搭建一个网站
  • wordpress三道杠菜单在线seo关键词排名优化
  • 抖音seo源码搭建百度关键词优化师
  • 云南工程建设信息网站东莞网站建设排名
  • 广州做网店哪个网站批发网广州seo运营
  • 黄龙云 加强网站建设廊坊seo网络推广
  • crm系统成功案例分享ppt网站seo优化步骤
  • 怎样把域名和做的网站连接总裁培训班
  • 如题,HTML如何将两张图片_一张放在网站顶部做背景,另一张放在尾部做背景?网页制作的步骤
  • 大前端网站百度在线搜索