在线等哈...进来发言送分,使用本板块置顶的IOCP封装类,在客户端发送数据时出现,堆被破坏

当我遇上-你 2011-10-31 03:14:05
代码如下
在线程中使用出现可能堆被破坏....
不开线程使用有完全正常,问下大家是怎么回事啊?
//发送数据
extern "C"
WIN32API
int SendPacket(SOCKET hSock,char * sendBuf,int nLen)
{
DWORD offset=0,total=0;
DWORD Flags = 0,SendByts = 0;
LPPER_IO_OPERATION_DATA PerIoData = NULL;
IOCP_HEADER header;
DWORD dwRet = 0;
int nPreLen = 8192,nNowLen = 0;
int nFiledLen = sizeof(int);

if(sendBuf == NULL) return 0;

//获取原始发送缓冲区大小
getsockopt(hSock,SOL_SOCKET,SO_SNDBUF,(char*)&nPreLen,&nFiledLen);
//设置新的发送缓冲区大小为0
setsockopt(hSock,SOL_SOCKET,SO_SNDBUF,(char*)&nNowLen,sizeof(nNowLen));

//分配单句柄数据内存
PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA));
if(PerIoData == NULL)
{
TRACE("分配内存失败\n");
return -1;
}

//计算总包数
total=nLen / PACKET_SIZE;
if(nLen % PACKET_SIZE != 0)total++;

memset(&header,0,sizeof(header));
//设置包标识符
header.Identify = (UINT)InterlockedIncrement((LONG*)&g_cId);
//设置总包数
SET_PACKET_COUNT(header.Flag,total);
for(DWORD i=0; i<total; i++)
{
//设置包头属性,拷贝包头
header.Offset = offset;
(i==(total-1))?SET_PACKET_END(header.Flag):RESET_PACKET_END(header.Flag);
(i==(total-1))?SET_PACKET_LEN(header.Flag,nLen % PACKET_SIZE):SET_PACKET_LEN(header.Flag,PACKET_SIZE);
header.CheckSum = header.Flag + header.Offset + header.Identify;

memset(PerIoData->Buffer,0,DATA_BUFSIZE);
//拷贝头数据
memcpy(PerIoData->Buffer,&header,sizeof(IOCP_HEADER));
//拷贝发送数据
memcpy(PerIoData->Buffer + sizeof(IOCP_HEADER),sendBuf + offset,GET_PACKET_LEN(header.Flag));
//调整位移
offset = offset + GET_PACKET_LEN(header.Flag);

Flags = 0;
PerIoData->DataBuf.len = sizeof(IOCP_HEADER) + GET_PACKET_LEN(header.Flag);
PerIoData->DataBuf.buf = PerIoData->Buffer;

//发送数据
if(WSASend(hSock, &(PerIoData->DataBuf), 1, &SendByts, Flags, NULL, NULL) == SOCKET_ERROR)
{
//如果不是“设备忙”错误,则关闭SOCKET,并删除与之相关的结构
if (WSAGetLastError() != ERROR_IO_PENDING)
{
TRACE("WSASend failed with error [%ld]\n",WSAGetLastError());
break;
}
}
//统计发送字节数
dwRet = dwRet + SendByts;
}
GlobalFree(PerIoData);

//设置发送缓冲区设置成原始大小
setsockopt(hSock,SOL_SOCKET,SO_SNDBUF,(char*)&nPreLen,sizeof(nPreLen));

return dwRet;
}


...全文
206 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
logens 2011-11-01
  • 打赏
  • 举报
回复
不太明白,顶一下
当我遇上-你 2011-11-01
  • 打赏
  • 举报
回复
今天测试了低版本的,暂时没发现内存问题,在继续测试其他方面的
yynetsdk 2011-11-01
  • 打赏
  • 举报
回复
看我的签名
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 maoxing63570 的回复:]
引用 14 楼 wswwxk 的回复:
这个实例简单测试了下,问题比板块的实例问题更多

咋这犀利
[/Quote]
也不见 飞机党 在这个版块活动了,在的话,还可以交流下
maoxing63570 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wswwxk 的回复:]
这个实例简单测试了下,问题比板块的实例问题更多
[/Quote]

咋这犀利
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 maoxing63570 的回复:]
引用 11 楼 wswwxk 的回复:

引用 9 楼 maoxing63570 的回复:
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅

是的,这个库在数据量大的情况下,有严重的内存泄露

如果是客户端出现泄露的话,那么我可能想到的就是你没用那个ReleasePacket来释放,对于服务端来说,那么他有个自定义堆,另外还有一个用模板写的小型池,也不知……
[/Quote]
不使用线程池,也会出问题,测试数据在1MB/S 以下正常,但是在10M/S左右的时候,内存迅速耗尽,使用量直线上升,明天在测试下
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 maoxing63570 的回复:]
引用 11 楼 wswwxk 的回复:

引用 9 楼 maoxing63570 的回复:
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅

是的,这个库在数据量大的情况下,有严重的内存泄露

貌似我没遇到过,如果用MFC的话,可以看下gh0st用的那个
http://www.codeproject.com/KB/IP/winsockiocp.aspx……
[/Quote]
这个实例简单测试了下,问题比板块的实例问题更多
maoxing63570 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wswwxk 的回复:]

引用 9 楼 maoxing63570 的回复:
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅

是的,这个库在数据量大的情况下,有严重的内存泄露
[/Quote]
如果是客户端出现泄露的话,那么我可能想到的就是你没用那个ReleasePacket来释放,对于服务端来说,那么他有个自定义堆,另外还有一个用模板写的小型池,也不知道你用没用线程池,还有就是,你怎么检测出有泄露的
maoxing63570 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wswwxk 的回复:]

引用 9 楼 maoxing63570 的回复:
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅

是的,这个库在数据量大的情况下,有严重的内存泄露
[/Quote]
貌似我没遇到过,如果用MFC的话,可以看下gh0st用的那个
http://www.codeproject.com/KB/IP/winsockiocp.aspx?msg=79399
当然,如果你要用心跳检测的话,你也可以直接去下个gh0st,然后从代码里提
小妹见的少,就这些了
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 maoxing63570 的回复:]
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅
[/Quote]
是的,这个库在数据量大的情况下,有严重的内存泄露
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 maoxing63570 的回复:]
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅
[/Quote]
你有比较好的IOCP实例吗?能分享下吗?之前没搞过网络....28733690@163.com
maoxing63570 2011-10-31
  • 打赏
  • 举报
回复
如果没记错的话,这个代码来源于飞机党发的一个开源的代码里,author是沈毅
Eleven 2011-10-31
  • 打赏
  • 举报
回复
你需要确保你的重叠结构体在发送的过程中不会被破坏,即在send发送数据的时候,没有地哦啊用GlobalFree来做释放操作
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tan625747 的回复:]
&(PerIoData->DataBuf)
明显这有问题

每循环一次,分配一次DataBuf
[/Quote]
这里只是引用地址,没分配空间,
//分配单句柄数据内存
PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA));
if(PerIoData == NULL)
{
TRACE("分配内存失败\n");
return -1;
}
//函数结束释放
GlobalFree(PerIoData);
v_table 2011-10-31
  • 打赏
  • 举报
回复
你的重叠结构对象就一个,怎么能投递多个异步IO呢!
tan625747 2011-10-31
  • 打赏
  • 举报
回复
&(PerIoData->DataBuf)
明显这有问题

每循环一次,分配一次DataBuf
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 oyljerry 的回复:]
估计线程同步等问题,数据是否有冲突访问
[/Quote]
只有一个线程,就只负责发送数据
oyljerry 2011-10-31
  • 打赏
  • 举报
回复
估计线程同步等问题,数据是否有冲突访问
凌乱哥 2011-10-31
  • 打赏
  • 举报
回复
标记,表示不太懂,顶一个
当我遇上-你 2011-10-31
  • 打赏
  • 举报
回复
也不是一开始就处问题,而是发送成功几次后就回出现这个问题,
WSASend(hSock, &(PerIoData->DataBuf), 1, &SendByts, Flags, NULL, NULL)
删除发送,代码没问题

18,363

社区成员

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

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