skval
May 22nd, 2009, 03:52 PM
Hi, i'm writing a server using the port completion architecture.
below the worker thread code.
the program crashes write after i queue the completion request, but the weird thing is that it crashes only if i send info that fills all the buffer in the WSAREcv function.
if for example the buffer size is 10 only 10 length string i'll send will make it crash.
any ideas?
thanks in advance for any help.
void CServer::HandleConnections()
{
OVERLAPPED *lpOverlapped=NULL;
DWORD dwTransfered;
PER_HANDLE_DATA *PerHandleData;
PER_IO_DATA *PerIoData;
while(1)
{
GetQueuedCompletionStatus(this->hCompletion,
&dwTransfered,
(LPDWORD)&PerHandleData,
&lpOverlapped,INFINITE);
PerIoData = CONTAINING_RECORD(lpOverlapped, PER_IO_DATA, Overlapped);
ResetEvent(PerIoData->Overlapped.hEvent);
//if WSARecv/WSASend returns 0 then connection was closed
if(dwTransfered==0 && (PerIoData->OperationType == RECV_POSTED ||
PerIoData->OperationType == SEND_POSTED))
{
WSACloseEvent(PerIoData->Overlapped.hEvent);
lpfnDisconnectEx(PerHandleData->Socket,NULL,TF_REUSE_SOCKET,0);
this->bFreeSockets[PerHandleData->iIndex]=TRUE;
delete PerHandleData;
delete PerIoData;
continue;
}
else if(PerIoData->OperationType == RECV_POSTED)
{
if(dwTransfered<0)
{
//error occured
}
else if(dwTransfered<3 && PerHandleData->bWriteDataToFile==FALSE)
{ //error occured
char szData[10];
sprintf(szData,"%c",iInvalidRequest);
//invalid request
//empty the buffer and send an INVALID_REQUEST error
//
WSASendWrapper(PerIoData,PerHandleData->Socket,szData);
}
//check if we need to write the data
else if(PerHandleData->bWriteDataToFile==TRUE)
{
//write the data to the file
}
else
{
PerIoData->dataBuf.buf[dwTransfered]=NULL;
if(PerIoData->dataBuf.buf[dwTransfered-2]!='\r'
&& PerIoData->dataBuf.buf[dwTransfered-1]!='\n')
{
char szData[10];
sprintf(szData,"%c",iInvalidRequest);
//invalid request
//empty the buffer and send an INVALID_REQUEST error
//
WSASendWrapper(PerIoData,PerHandleData->Socket,szData);
}
else
{
printf("%s",PerIoData->dataBuf.buf);
WSARecvWrapper(PerIoData,PerHandleData->Socket);
}
//make sure the command is valid
//and if it's not send an invalid request message
}
}
else if(PerIoData->OperationType==SEND_POSTED)
{
this->WSARecvWrapper(PerIoData,PerHandleData->Socket);
}
else if(PerIoData->OperationType==SHUTDOWN_SERVER)
{
SetEvent(hCompletionDone);
delete PerHandleData;
delete PerIoData;
break;
}
}
}
below the worker thread code.
the program crashes write after i queue the completion request, but the weird thing is that it crashes only if i send info that fills all the buffer in the WSAREcv function.
if for example the buffer size is 10 only 10 length string i'll send will make it crash.
any ideas?
thanks in advance for any help.
void CServer::HandleConnections()
{
OVERLAPPED *lpOverlapped=NULL;
DWORD dwTransfered;
PER_HANDLE_DATA *PerHandleData;
PER_IO_DATA *PerIoData;
while(1)
{
GetQueuedCompletionStatus(this->hCompletion,
&dwTransfered,
(LPDWORD)&PerHandleData,
&lpOverlapped,INFINITE);
PerIoData = CONTAINING_RECORD(lpOverlapped, PER_IO_DATA, Overlapped);
ResetEvent(PerIoData->Overlapped.hEvent);
//if WSARecv/WSASend returns 0 then connection was closed
if(dwTransfered==0 && (PerIoData->OperationType == RECV_POSTED ||
PerIoData->OperationType == SEND_POSTED))
{
WSACloseEvent(PerIoData->Overlapped.hEvent);
lpfnDisconnectEx(PerHandleData->Socket,NULL,TF_REUSE_SOCKET,0);
this->bFreeSockets[PerHandleData->iIndex]=TRUE;
delete PerHandleData;
delete PerIoData;
continue;
}
else if(PerIoData->OperationType == RECV_POSTED)
{
if(dwTransfered<0)
{
//error occured
}
else if(dwTransfered<3 && PerHandleData->bWriteDataToFile==FALSE)
{ //error occured
char szData[10];
sprintf(szData,"%c",iInvalidRequest);
//invalid request
//empty the buffer and send an INVALID_REQUEST error
//
WSASendWrapper(PerIoData,PerHandleData->Socket,szData);
}
//check if we need to write the data
else if(PerHandleData->bWriteDataToFile==TRUE)
{
//write the data to the file
}
else
{
PerIoData->dataBuf.buf[dwTransfered]=NULL;
if(PerIoData->dataBuf.buf[dwTransfered-2]!='\r'
&& PerIoData->dataBuf.buf[dwTransfered-1]!='\n')
{
char szData[10];
sprintf(szData,"%c",iInvalidRequest);
//invalid request
//empty the buffer and send an INVALID_REQUEST error
//
WSASendWrapper(PerIoData,PerHandleData->Socket,szData);
}
else
{
printf("%s",PerIoData->dataBuf.buf);
WSARecvWrapper(PerIoData,PerHandleData->Socket);
}
//make sure the command is valid
//and if it's not send an invalid request message
}
}
else if(PerIoData->OperationType==SEND_POSTED)
{
this->WSARecvWrapper(PerIoData,PerHandleData->Socket);
}
else if(PerIoData->OperationType==SHUTDOWN_SERVER)
{
SetEvent(hCompletionDone);
delete PerHandleData;
delete PerIoData;
break;
}
}
}