18,356
社区成员
发帖
与我相关
我的任务
分享
int WSARecvFrom(
__in SOCKET s,
__in_out LPWSABUF lpBuffers,
__in DWORD dwBufferCount,
__out LPDWORD lpNumberOfBytesRecvd,
__in_out LPDWORD lpFlags,
__out struct sockaddr* lpFrom,
__in_out LPINT lpFromlen,
__in LPWSAOVERLAPPED lpOverlapped,
__in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
这个函数第6、7两个参数(lpFrom,lpFromlen),在数据接收完成前,不能被销毁。 尤其注意第7个参数!也就是lpFromlen,之前我就是疏忽,直接取了局部变量的地址传入。导致程序崩溃都不知道崩在哪。找了好久才注意到这个,修改之后,再也没崩溃过。。。
EnterCriticalSection(&rcvUdpDataIocpSection);
iRcvNum++;
__try
{
if (rcvDataHandler
&& pIoContext
&& pIoContext->m_szBuffer
&& //条件要判断充分
&& 1)
{
(*(this->rcvDataHandler))(this->clientData,
(unsigned char*)pIoContext->m_szBuffer, dwLen, pIoContext->addr, 0);
}
bool brst = this->PostRecvUdp(pIoContext, iThreadId);
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
ASSERT(FALSE);
}
LeaveCriticalSection(&rcvUdpDataIocpSection);
BOOL bReturn = GetQueuedCompletionStatus(svrInfo->m_hIOCompletionPort, &dwBytesTransferred, (PULONG_PTR)&pSocketContext, &pOverLapped, INFINITE);
if (!bReturn) {
DWORD dErr = GetLastError();
PER_IO_CONTEXT *pIoContext = CONTAINING_RECORD(pOverLapped, PER_IO_CONTEXT, overLapped);
svrInfo->HandleQueueCompletionErr(pSocketContext, pIoContext, dErr);
}
else {
PER_IO_CONTEXT *pIoContext = CONTAINING_RECORD(pOverLapped, PER_IO_CONTEXT, overLapped);
switch (pIoContext->opType)
{
case RECVUDP_POST:
if (pSocketContext) {
pSocketContext->DoRecvUdp(pIoContext, dwBytesTransferred, iThreadId);
}
}
}