IOCP写的UDP!
在测试中,我不断的创建套接字,并在此套接字上发送和接收数据,会同时有很多个套接字在发送和接收数据!!!
运行一段时间之后,会弹出对话框报错:
Access violation at address 00000010 Read address of 00000010.
有时候还报错USER32.DLL中非法!!
郁闷了!!!!!
应该不是我代码中访问非法,应该是IOCP内部的报出来的,到底是怎么回事啊????
有哪位能给我说说,造成这个问题的可能原因也好!!!!!
我在网上也查了很多,但是都是说的TCP的IOCP,我在调试的过程中,查看日志,实在没看出来是什么问题,难道是overlapped结构的问题???我资源的释放是采取的引用计数方式来的,感觉应该没有什么问题!!!!!
有经验的,给我指点,谢谢!!!
在测试中,我不断的创建套接字,并在此套接字上发送和接收数据,会同时有很多个套接字在发送和接收数据!!!
运行一段时间之后,会弹出对话框报错:
Access violation at address 00000010 Read address of 00000010.
有时候还报错USER32.DLL中非法!!
郁闷了!!!!!
应该不是我代码中访问非法,应该是IOCP内部的报出来的,到底是怎么回事啊????
有哪位能给我说说,造成这个问题的可能原因也好!!!!!
我在网上也查了很多,但是都是说的TCP的IOCP,我在调试的过程中,查看日志,实在没看出来是什么问题,难道是overlapped结构的问题???我资源的释放是采取的引用计数方式来的,感觉应该没有什么问题!!!!!
有经验的,给我指点,谢谢!!!
解决方案 »
- MFC
- 重叠 io 有一个函数,如果失败,那么需要再次调用,它叫什么啊?
- 关于IsWindowVisible GetTopWindow与GetDeskTopWindow
- 100求教~~如何将指定位置的bmp图片像素值保存到一个数组中?
- 用CObList类的AddTail加入的的指针(用new分配的),用不用再释放?
- 请教:两个多边形A与B相交后,想要得到一个新的多边形C,怎么实现?
- VC中关于DXSDK的配置问题
- 怎样在VISUAL STUDIO .NET 的开发环境中执行老式的WIN32程序?
- 在main()主函数里,可以有以下这样的语句吗?
- 如果快速画网格???
- post请求的 Cookie字段值的问题
- 向静态文本框中显示图片不成功
unsigned __stdcall CSockBase::ReceiveThread( void* pArg )
{
CSockBase *pThis = (CSockBase*)pArg;
assert(pThis != NULL);
HANDLE hIOCP = pThis->GetIOCPHandle();
assert(hIOCP != NULL);
DWORD dwTrans = 0;
DWORD dwKey = 0;
PER_HANDLE_DATA *pHandleData = NULL;
PER_IO_DATA *pIoData = NULL;
BOOL bRet = FALSE;
while(1)
{
bRet = GetQueuedCompletionStatus(hIOCP, &dwTrans, &dwKey, (LPOVERLAPPED*)&pIoData, INFINITE);
pHandleData = (PER_HANDLE_DATA*)dwKey;
if(!bRet)
{
if(GetLastError() == WAIT_TIMEOUT)
{
continue;
}
else
{
if(pIoData == NULL) //关闭套接字引起
{
ATLTRACE("---关闭套接字引起---\r\n");
CAutoLock(&(pThis->m_ListIoInUsecs), "Receivethread");
pThis->FreeIoData(pIoData, pHandleData);
continue;
}
ATLTRACE("Quit from receive thread : %d errorcode : %d \r\n", GetCurrentThreadId(), GetLastError());
return -1;
}
}
if(dwTrans == OPER_CLOSE && pHandleData->bIsClose)
{
while(pHandleData->dwSendOutstandingCount != 0)
{
ATLTRACE("未完成 Socket: %d Count: %d \r\n", pHandleData->s, pHandleData->dwSendOutstandingCount);
Sleep(10);
}
pThis->FreeHandleData(pHandleData);
ATLTRACE("Complete Closesocket address : %x \r\n", dwKey);
continue;
}
if(dwTrans == OPER_QUIT)
{
ATLTRACE(_T("Quit from receive thread: %d \r\n"), GetCurrentThreadId());
break;
}
pThis->HandleIo(dwKey, dwTrans, (DWORD)pIoData);
}
return 0;
}
void CSockBase::HandleIo(DWORD dwKey, DWORD dwTrans, DWORD dwOvl)
{
INT nRet = 0;
WSABUF buf;
DWORD dwFlag = 0;
INT nLen = sizeof(SOCKADDR);
PER_HANDLE_DATA *pHandleData = (PER_HANDLE_DATA*)dwKey;//单句柄数据
PER_IO_DATA *pIoData = (PER_IO_DATA*)dwOvl;//单IO数据
if(pHandleData->bIsClose && pIoData->byOperType == OPER_READ)
{
ATLTRACE("Read rubbish packet socket: %x bIsClose : %x handle address : %x Operation Type : %d \r\n",
pHandleData->s, pHandleData->bIsClose, pHandleData, pIoData->byOperType);
return;
}
switch(pIoData->byOperType)
{
case OPER_READ:
{
DATA *pData = AllocData();
pData->dwIndex = (DWORD)pHandleData->s;
memcpy(pData->szLocalIp, inet_ntoa(pHandleData->localAddr.sin_addr), IP_LEN);
pData->wLocalPort = ntohs(pHandleData->localAddr.sin_port); //单IO数据
assert(pIoData->ol.InternalHigh <= MAX_BUF);
memcpy(pData->szData, pIoData->szBuf, pIoData->ol.InternalHigh);
memcpy(pData->szPeerIp, inet_ntoa(pIoData->RemoteAddr.sin_addr), IP_LEN);
pData->wDataLen = (WORD)pIoData->ol.InternalHigh;
pData->wPeerPort = ntohs(pIoData->RemoteAddr.sin_port);
while(!HasOverlappedIoCompleted(&pIoData->ol)) //等待overlapped结构完成
{
ATLTRACE("HandleIo didn't Complete \r\n");
Sleep(0);
}
{
CAutoLock LockList(&m_ListIoInUsecs, "HandleIo Read");
FreeIoData(pIoData, pHandleData); //用完后释放IO数据
InterlockedDecrement(&pHandleData->dwRecvOutstandingCount); //递减未决接收IO计数
ATLTRACE("Release Io Buffer Recv Count : %d \r\n", pHandleData->dwRecvOutstandingCount);
pIoData = NULL;
}
//投递接收请求
pIoData = AllocIoData();
ATLTRACE("AllocIoData for socket : %d Address : 0x%x\r\n", pHandleData->s, pIoData);
if(pIoData == NULL)
{
ATLTRACE("申请IO失败! \r\n");
return;
} {
CAutoLock LockList(&m_ListIoInUsecs, "HandleIo");
pHandleData->ListIoData.push_back(pIoData);
}
ATLTRACE("申请读节点,地址:0x%x \r\n", pIoData); buf.buf = pIoData->szBuf;
buf.len = MAX_BUF;
pIoData->byOperType = OPER_READ;
//增加接收请求计数
nRet = WSARecvFrom(pHandleData->s, &buf, 1, NULL, &dwFlag, (SOCKADDR*)&(pIoData->RemoteAddr), &nLen, &(pIoData->ol), NULL);
if(nRet == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
ATLTRACE("Recv request failed ! HandleIoData errorcode: %d \r\n", WSAGetLastError());
{
CAutoLock LockList(&m_ListIoInUsecs, "err recv");
FreeIoData(pIoData, pHandleData);
}
return;
}
InterlockedIncrement(&pHandleData->dwRecvOutstandingCount);
//向数据队列中加入数据
{
CAutoLock LockDeque(&m_Dequecs, "HandleIo DequeData");
m_dequeData.push_back(pData);
} PostMessage(m_hMsgWnd, WM_GETDATA, 0, (LPARAM)this);//通知接收数据
break;
}
case OPER_SEND:
{
//递减请求计数
{
CAutoLock LockList(&m_ListIoInUsecs, "HandleIo Deque Data");
FreeIoData(pIoData, pHandleData);
InterlockedDecrement(&pHandleData->dwSendOutstandingCount);
ATLTRACE("Release IOBuffer after Send Sendcount: %d \r\n", pHandleData->dwSendOutstandingCount);
}
break;
}
default:
break;
}
return;
}帮我看看,在哪里出了问题!谢谢!!
电脑配置如下:
1.CPU: AMD4000+ 2.内存:GelllG1667 3.硬盘:WD160G 4.主板:GMK8T890 5.显卡:七彩虹8400GS 6.外带摄像头,音响,键盘,鼠标 7.卖主机送显示器{纯平显示器} 有意者请拨:13419523734 或QQ:450445043 或直接到学生公寓3栋625看电脑.....
有个重要的问题要提醒楼主的是在多线程编程中,若使用的系统windows平台,那么一个进程能开辟的最大内存在2G左右,而Linux中好像是没有这个限制的。楼主的程序应该是单进程多线程的,所以也必须考虑内存限制。
以上仅是我编程中一些经验希望对你有用的!
buf.len = MAX_BUF;
是不是等待接收的套接字太多,而真正接收的数据很少,使得大量unpaged的内存被使用,导致的问题。
楼主看看这一块内存是否被释放了。
1。只发起连接,但客户端不发送数据,直至处理异常,看看是否也会出现同样的问题,验证我上面说的情况是否属实。
2。监控内存变化,是否只增不减。
while(1)
{
//写到这里
DWORD dwTrans = 0;
DWORD dwKey = 0;
PER_HANDLE_DATA *pHandleData = NULL;
PER_IO_DATA *pIoData = NULL;
BOOL bRet = FALSE; bRet = GetQueuedCompletionStatus(hIOCP, &dwTrans, &dwKey, (LPOVERLAPPED*)&pIoData, INFINITE); // 你这下面都释放掉了,你也不复位,不死才怪了. }
{
ATLTRACE("---关闭套接字引起---\r\n");
CAutoLock(&(pThis->m_ListIoInUsecs), "Receivethread");
pThis->FreeIoData(pIoData, pHandleData);
continue;
}
其他地方(比如内存分配,socket创建是否成功等等)也检查一下
const int Add = 10; const int ADDPriority = 4; // +
const int Subtract = 9; const int SubtractPriority = 4; // -
const int Less = 8; const int LessPriority = 3; // <
const int LessEqual = 7; const int LessEqualPriority = 3; // <=
const int Great = 6; const int GreatPriority = 3; // >
const int GreatEqual = 5; const int GreatEqualPriority = 3; // >=
const int EqualEqual = 4; const int EqualEqualPriority = 3; // ==
const int And = 3; const int AndPriority = 2; // &&
const int OR = 2; const int ORPriority = 2; // ||
const int Equal = 1; const int EqualPriority = 1; // =
//---------------------------------------------------------------------------
//---- 运算符标识名 ----- --------- 优先级 --------------- --- 说明 ---
const int Add = 10; const int ADDPriority = 4; // +
const int Subtract = 9; const int SubtractPriority = 4; // -
const int Less = 8; const int LessPriority = 3; // <
const int LessEqual = 7; const int LessEqualPriority = 3; // <=
const int Great = 6; const int GreatPriority = 3; // >
const int GreatEqual = 5; const int GreatEqualPriority = 3; // >=
const int EqualEqual = 4; const int EqualEqualPriority = 3; // ==
const int And = 3; const int AndPriority = 2; // &&
const int OR = 2; const int ORPriority = 2; // ||
const int Equal = 1; const int EqualPriority = 1; // =
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 运算符标识名 优先级 运算符
//---------------------------------------------------------------------------
const int Add = 10; const int ADDPriority = 4; // +
const int Subtract = 9; const int SubtractPriority = 4; // -
//---------------------------------------------------------------------------
const int Less = 8; const int LessPriority = 3; // <
const int LessEqual = 7; const int LessEqualPriority = 3; // <=
const int Great = 6; const int GreatPriority = 3; // >
const int GreatEqual = 5; const int GreatEqualPriority = 3; // >=
const int EqualEqual = 4; const int EqualEqualPriority = 3; // ==
//---------------------------------------------------------------------------
const int And = 3; const int AndPriority = 2; // &&
const int OR = 2; const int ORPriority = 2; // ||
//---------------------------------------------------------------------------
const int Equal = 1; const int EqualPriority = 1; // =
//---------------------------------------------------------------------------
{
enumInvalid = 0, // 0:无效值
enumOperator = 1, // 1:operator 运算符项
enumIntParam = 2, // 2:intParam 参数项, 其值为int
enumSzParam = 3, // 3:szParam 参数项, 其值为字符串
//enumFunction = 9 // 9:function 参数项,
};
//Expression= " (%sUserType@ == %s1@) && (%sMSISDN@ > %s138@) && KDJ || %sabc@ "struct/class ExpressionItem
{
int iItemType; // 1:operator, 2:intParam, 3:szParam, ... 9:function;
// 1:operator
int iOperType; // 标识运算符 (>, >=, <=, <, ==, =, ||, &&, !)
int iOperPriority; // 1, 2, 3, 11, 112, 113, 1113; <--每深入一层括号,优先级前面加1。 // 2:intParam (或运算过程中的 中间值)
int iParam; // 3:szParam (或中间值)
char szParam[48]; // 表达式的字符串项: "MSISDN@",
};
/*
* Comments about bug in OnWrite() added 051227..
*
* This BUG was difficult to find. The bug was found after 6 hours of
* extensive debugging with several debug tools as Rational Test Suite,
* SoftICe , VC++ DEBUG, GLOWCODE, etc. I Found that in some rarely bizarre
* cases (when a client rapidly disconnect & reconnect, etc..) we get an
* access violation , etc. First of all we had one ReleaseClientContext to many
* in OnWrite() which caused access violation. Second when I remove it, I found
* that sometimes the client specific data (e.g. ClientContext) does not removed/relesed
* from memory, even if the client is disconnected. The reason in not
* intuitive and do not ask me how I figured it out. The problem occurs
* when an send is not ordered (see http://www.codeproject.com/internet/iocp_server_client.asp,
* section "3.6.2 The package reordering problem" for more information ) and
* we call the function GetNextSendBuffer(pContext,pOverlapBuff); (above) in Onwrite(..),
* to get the correct buffer to process. At exactly this point the remote client disconnects
* and this leads to the bug. Now I got tired of explaining this hassling stuff, so lets
* go to the business the fix is below..
这段解释和我的情况有点相同,不知和你的情况怎样?
2,对于 IOCP 线程的理解,以及内存释放的控制,要求还是挺高的
楼主的错误就跟 0xC0000005 一样的,非法访问内存,检查初始化分配和释放吧