完成端口的问题

yangyanzhao 2017-07-24 08:20:44
PER_SOCKET_CONTEXT* pNewSocketContext = new PER_SOCKET_CONTEXT;
pNewSocketContext->m_Socket = pIoContext->m_sockAccept;
//memcpy(&(pNewSocketContext->m_ClientAddr), ClientAddr, sizeof(SOCKADDR_IN));

PER_IO_CONTEXT* pNewIOContext = pNewSocketContext->GetNewIoContext();
//PER_IO_CONTEXT* pNewIOContext;
pNewIOContext->m_OpType = RECV_POSTED;
//pNewIOContext->m_OpType = ACCEPT_POSTED;
pNewIOContext->m_sockAccept = pIoContext->m_sockAccept;
memcpy(pNewIOContext->m_szBuffer, pIoContext->m_szBuffer, MAX_BUFFER_LEN);
memset(&pNewIOContext->m_Overlapped, 0, sizeof(OVERLAPPED));

以上代码运行一段时间后就出现内存错误
_PER_IO_CONTEXT* GetNewIoContext()
{
_PER_IO_CONTEXT* p = new _PER_IO_CONTEXT;

m_arrayIoContext.Add( p );

return p;
}
申请不到内存
...全文
273 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangyanzhao 2017-08-02
  • 打赏
  • 举报
回复
PER_IO_CONTEXT* pNewIOContextSend = pSocketContext->GetNewIoContextSend(); switch( pIoContext->m_OpType ) { // Accept case ACCEPT_POSTED: { // 为了增加代码可读性,这里用专门的_DoAccept函数进行处理连入请求 pIOCPModel->_DoAccept(pSocketContext, pNewIOContextSend, pIoContext); /*if (pNewIOContextSend->m_sockAccept != INVALID_SOCKET){ pSocketContext->RemoveContextSend(pNewIOContextSend); }*/ //pIOCPModel->_RemoveContext(pSocketContext); //pSocketContext->RemoveContext(pNewIOContext); //pIOCPModel->_DoAccept(pSocketContext, pNewIOContext, pIoContext); } break; // RECV case RECV_POSTED: { // 为了增加代码可读性,这里用专门的_DoRecv函数进行处理接收请求 //pIOCPModel->_DoRecv( pSocketContext,pIoContext ); pIOCPModel->_DoRecv(pSocketContext,pNewIOContextSend, pIoContext); /*if (pNewIOContextSend->m_sockAccept!=INVALID_SOCKET){ pSocketContext->RemoveContextSend(pNewIOContextSend); }*/ //pIOCPModel->_RemoveContext(pSocketContext); //pSocketContext->RemoveContext(pNewIOContext); } break; // SEND // 这里略过不写了,要不代码太多了,不容易理解,Send操作相对来讲简单一些 case SEND_POSTED: { /*pNewIOContext->m_OpType = SEND_POSTED; pNewIOContext->m_sockAccept = pIoContext->m_sockAccept; memcpy(pNewIOContext->m_szBuffer, pIoContext->m_szBuffer, MAX_BUFFER_LEN); memset(&pNewIOContext->m_Overlapped, 0, sizeof(OVERLAPPED)); pNewIOContext->totalByte = length; pIoContext->m_OpType = SEND_POSTED;*/ if (dwBytesTransfered < pIoContext->totalByte){ pIOCPModel->Send(pSocketContext, pNewIOContextSend, pIoContext, pIoContext->m_sockAccept, pIoContext->m_szBuffer + dwBytesTransfered, 0, pIoContext->totalByte - dwBytesTransfered); } pSocketContext->RemoveContextSend(pNewIOContextSend); //WSACloseEvent(pNewIOContext->m_Overlapped.hEvent); //pSocketContext->RemoveContext(pNewIOContext); //WSAResetEvent(pIoContext->m_Overlapped.hEvent); //WSASend(pIoContext->m_sockAccept, &pIoContext->m_szBuffer, ); } break; default: // 不应该执行到这里 TRACE(_T("_WorkThread中的 pIoContext->m_OpType 参数异常.\n")); timeStr = pIOCPModel->GetTimeStr(timeStr1); pIOCPModel->str.Format("%s workthread %d pIoContext->m_OpType unknown!\n", timeStr.c_str(),nThreadNo); pIOCPModel->logFile.write(pIOCPModel->str, pIOCPModel->str.GetLength()); break; } //switch 还是有句柄泄露
赵4老师 2017-07-27
  • 打赏
  • 举报
回复
yangyanzhao 2017-07-26
  • 打赏
  • 举报
回复
数据处理完成后释放后出1236错误,工作线程GetQueuedCompletionStatus返回出错退出了。。。
xian_wwq 2017-07-26
  • 打赏
  • 举报
回复
引用 7 楼 yangyanzhao 的回复:
PER_IO_CONTEXT应该在工作者线程的什么位置释放?
GetQueuedCompletionStatus返回就意味着投递完成了, 根据业务要求把数据处理后,就可以释放了
yangyanzhao 2017-07-26
  • 打赏
  • 举报
回复
PER_IO_CONTEXT应该在工作者线程的什么位置释放?
worldy 2017-07-25
  • 打赏
  • 举报
回复
引用 4 楼 yangyanzhao 的回复:
我不知道完成端口中_PER_IO_CONTEXT应该在哪里释放,我试过在Worker线程返回通知后释放,但会出1236号错误,可能主机还在使用,释放掉的话主机积极关闭连接了。
引用 4 楼 yangyanzhao 的回复:
我不知道完成端口中_PER_IO_CONTEXT应该在哪里释放,我试过在Worker线程返回通知后释放,但会出1236号错误,可能主机还在使用,释放掉的话主机积极关闭连接了。
IOCP的线程,原则上是一直运行,不会退出的,一般_PER_IO_CONTEXT是在每个IO返回后就要释放,但是Overlap数据是可以回收重用的
xian_wwq 2017-07-24
  • 打赏
  • 举报
回复
如果投递完成后的对象都正常释放了 申请内存不足有可能是内存碎片太多 可以考虑使用内存池 可以提高效率 避免内存碎片
worldy 2017-07-24
  • 打赏
  • 举报
回复
_PER_IO_CONTEXT一直申请,你不在使用的是时候要删除
sevancheng 2017-07-24
  • 打赏
  • 举报
回复
没有进行内存释放吧,用完要回收,或者用智能指针试试
Lytton_jing 2017-07-24
  • 打赏
  • 举报
回复
学习学习 http://blog.csdn.net/ddjj_1980/article/details/74940593
yangyanzhao 2017-07-24
  • 打赏
  • 举报
回复
我不知道完成端口中_PER_IO_CONTEXT应该在哪里释放,我试过在Worker线程返回通知后释放,但会出1236号错误,可能主机还在使用,释放掉的话主机积极关闭连接了。
Re:CCNA_CCNP 思科网络认证 PAT NAT 端口或地址转换 与端口映射======================# 本章课程大纲        公网地址和私网地址        NAT应用场景        静态NAT  :static  地址转换        动态NAT  :dynamic地址转换        PAT        :端口地址转换        端口映射 :port map        在Windows上同时实现的NAT和端口映射 # 私网地址三类 A类:10.0.0.0                                255.0.0.0(1网段) B类:172.16.0.0 -172.31.0.0         255.255.0.0(16网段) C类:192.168.0.0-192.168.255.0  255.255.255.0(255网段) # NAT 的使用场景        NAT的最初的目的是允许把私有IP地址映射到公网地址,以减缓IP地址空间的消耗。        当一个组织更换它的互联网服务提供商ISP,但不想更改内网配置方案时,NAT同样很有用途。        以下是适于使用NAT的多种情况:         企业内网接入Internet节省公网地址         单向访问         大方向:内网访问互联网(互联网上主机不能够访问内网主机)         小方向:同单位实现两个网段之间单向访问(涉密部门能够访问其他部门,反之不可)         增加一个网段          避免在主干路由器增加到这个网段的路由         在Windows上实现的NAT和端口映射 # 网络地址转换的类型        下面介绍一下NAT的三种类型。         静态NAT 是为了在私网地址和公网地址间,允许一对一映射而设计的。         或者IPv4和IPv6之间的转换(典型)         不节省公网地址,故公网地址的利用效率不高,         无任何安全性,外网可以通过公网地址直接攻击内网主机,好像只增加路由器的工作         适用场景类似代理,可以较方便的更换主机,而无需修改路由器的配置         故应用不够广泛...         动态NAT 可以实现映射一个未注册 IP地址到注册IP地址池中的一个注册IP地址。         多对一,或多对多         比较PAT优势:避免被误认为攻击而被封ip地址         不太节省地址,应用不广泛         复用是最流行的NAT配置类型,也被称为端口地址映射(PAT)。         通过使用PAT,可实现上千个用户仅通过一个真实的全球 IP地址连接到Internet。         缺点:增加延迟,消耗路由器性能 # 端口映射(port mapping) 允许Internet上的计算机通过企业路由器的公网IP地址访问到内网的服务器------------------------------------------------         

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧