Hi everyone. Someone could tell me how can i close a socket client when
i'm ensure that the client has received all data? I used the overlapped
socket and all things seems to work fine, but when i send the response
to the client, i see that the socket client is closed event if the
client hasn't completed the read operation.

Here is the code of the send and read, server side

//--------------------------------------------------------------
unsigned __stdcall CGenericServer::ClientThread(LPVOID pParam)
{
NewConnectionTag *pNewConn = (NewConnectionTag*)pParam;
CGenericServer *pGenericServer = pNewConn->pGenericServer;
SOCKET s = pNewConn->s;

int result;

//BOOL bResend = FALSE;
WSABUF Buffer;
DWORD NumberOfBytesSent;
DWORD dwBytesSent = 0;
//BOOL bKeepAlive = FALSE;
//BOOL bSendHeader;
char * sResponseBuffer = NULL;
int iPacketLength = 0;

WSRequest * pRequest = new WSRequest();
WSResponse * pResponse = new WSResponse();

pRequest->user = getRemoteUser(s);

lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Read Request
from Client Socket" );

DWORD NumberOfBytesRecvd = 0;
char szBuffer[MAX_BUFFER];
result = CGenericServer::ReceivePacket(s,
szBuffer,
MAX_BUFFER,
&NumberOfBytesRecvd,
pGenericServer->ShutdownEvent);
if(result != SOCKET_ERROR)
{
pGenericServer->Stats.nTotalRecv += (double)NumberOfBytesRecvd /
1024;

//
// Chech if we got complete request
//
if(pRequest->szRequest == NULL)
pRequest->szRequest = (char *)malloc(MAX_BUFFER*sizeof(char));

memcpy(pRequest->szRequest,szBuffer ,NumberOfBytesRecvd);
pRequest->szRequest[NumberOfBytesRecvd] = '\0';

if(strlen(pRequest->szRequest) > MAXLOGLINELEN)
lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Request
arrived: To Long for logging" );
else
lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Request
arrived: %s", pRequest->szRequest);
if(!pGenericServer->IsComplete(pRequest->szRequest)) {
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread:
Incompleate HTTP request");
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(NULL, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}


if(!pGenericServer->ParseRequest(pRequest))
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: Parsing
Request...");
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(NULL, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

//Perform Request
if(!pGenericServer->PerformeRequest(pRequest, pResponse))
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: Performing
Request...");
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(NULL, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

//
// Send Response to client
//

NumberOfBytesSent = 0;
dwBytesSent = 0;

lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: header:
%s", pResponse->szResponseHeader);

lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: body
length: %ld", pResponse->iBufferLenght);

if(pResponse->iBufferLenght< MAXLOGLINELEN)
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: %s",
pResponse->response);

iPacketLength = strlen(pResponse->szResponseHeader) +
pResponse->iBufferLenght;

sResponseBuffer = (char *)malloc(sizeof(char) * iPacketLength);
memcpy(sResponseBuffer, pResponse->szResponseHeader,
strlen(pResponse->szResponseHeader));
memcpy(&sResponseBuffer[strlen(pResponse->szResponseHeader)],
pResponse->response, pResponse->iBufferLenght);

do
{
result = SendPacket(s,
&sResponseBuffer[dwBytesSent],
((iPacketLength - dwBytesSent) >= SENDBLOCK) ? SENDBLOCK :
(iPacketLength - dwBytesSent),
&NumberOfBytesSent,
pGenericServer->ShutdownEvent);

if(SOCKET_ERROR != result)
{
dwBytesSent += NumberOfBytesSent;
}
}
while((dwBytesSent < iPacketLength) && (SOCKET_ERROR != result ||
result != WSAEWOULDBLOCK));

if(SOCKET_ERROR != result)
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread:
Aggiornamento dati a video" );
pGenericServer->Stats.nTotalSent += (double)dwBytesSent / 1024;
pGenericServer->DataSent(dwBytesSent);
}
else
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::ClientThread:
WSASend(...) failure %d", WSAGetLastError());
//pRequest->bKeepAlive = FALSE;
}

if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(NULL, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;

}
else {
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: WSAReceive
Failure: %d", WSAGetLastError());
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(NULL, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

}

int CGenericServer::ReceivePacket(SOCKET s, char * pBuf, DWORD
dwBufSize ,DWORD * NumberOfBytesReceived, HANDLE hExit)
{
WSABUF wsabuf;
WSAOVERLAPPED over;
DWORD dwRecv;
DWORD dwFlags;
DWORD dwRet;
HANDLE hEvents[2];
bool fPending;
int nRet;

*NumberOfBytesReceived = 0;

// ----------------------------------------------
// Zero the buffer so the recv is null-terminated
// ----------------------------------------------
memset(pBuf, 0, dwBufSize);
memset(&over, 0, sizeof(WSAOVERLAPPED));
// ---------------------------------------------
// Setup the WSABUF and WSAOVERLAPPED structures
// ---------------------------------------------
wsabuf.buf = pBuf;
wsabuf.len = dwBufSize;
over.hEvent = WSACreateEvent();

dwFlags = MSG_PEEK;
fPending = false;
nRet = WSARecv(s, // Socket
&wsabuf, // WSABUF
1, // Number of buffers
&dwRecv, // Bytes received
&dwFlags, // Flags
&over, // WSAOVERLAPPED
NULL); // Completion function
if (nRet != 0)
{
// here is something wrong with WSARevv ...
// ...
if (WSAGetLastError() != WSA_IO_PENDING)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ReceivePacket: Error
Read from socket %d", WSAGetLastError());
//AnsiString str = "W SARecv(): ";
//str += IntToStr(WSAGetLastError());

//form->output->Lines->Add(str);

CloseHandle((HANDLE)over.hEvent);
return WSAGetLastError();
}
else
fPending = true;

}

//NumberOfBytesReceived = dwRecv;

//form->output->Lines->Add("fPending = TRUE");
//fPending = true;

// ----------------------------
// If the I/O isn't finished...
// ----------------------------
if (fPending)
{
// --------------------------------------------------
// Wait for the request to complete or the exit event
// --------------------------------------------------
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ReceivePacket: Operation
pending...");

/*hEvents[0] = (HANDLE)over.hEvent;
hEvents[1] = hExit;*/
dwRet = WaitForSingleObject(over.hEvent,60000);
/*dwRet = WaitForMultipleObjects(2,
hEvents,
FALSE,
INFINITE);*/
// ----------------------------
// Was the recv event signaled?
// ----------------------------
if (dwRet != 0)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ReceivePacket: Error in
Receive Packet");
//form->output->Lines->Add("dwRet in RecvRequest()");
CloseHandle((HANDLE)over.hEvent);
return dwRet;
}
if (!WSAGetOverlappedResult(s,
&over,
&dwRecv,
FALSE,
&dwFlags))
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ReceivePacket:
WSAGetOverlappedResult() in RecvRequest()");
//form->output->Lines->Add("WSAGetOverlappedResult() in
RecvRequest()");
CloseHandle((HANDLE)over.hEvent);
return dwRet;
}
}

// -----------------------------------------
// Recv event is complete -- keep statistics
// -----------------------------------------
*NumberOfBytesReceived = dwRecv;
CloseHandle((HANDLE)over.hEvent);
return dwRecv;

}

int CGenericServer::SendPacket(SOCKET s, char * pBuf, int
iPacketLenght, DWORD * NumberOfBytesSent, HANDLE hExit)
{
WSABUF wsabuf;
WSAOVERLAPPED over;
DWORD dwSent;
DWORD dwFlags;
DWORD dwRet;
DWORD dwBytesReturned;
HANDLE hEvents[2];
bool fPending;
int nRet;

*NumberOfBytesSent = 0;
// ---------------------------------------------
// Setup the WSABUF and WSAOVERLAPPED structures
// ---------------------------------------------

memset(&over, 0, sizeof(WSAOVERLAPPED));
DWORD dwFlag = 0;
wsabuf.buf = pBuf;
wsabuf.len = iPacketLenght;
over.hEvent = WSACreateEvent();

fPending = FALSE;
nRet = WSASend(s, // Socket
&wsabuf, // WSABUF
1, // Number of buffers
&dwSent, // Bytes sent
dwFlag, // Flags
&over, // WSAOVERLAPPED
WSASendCompletionROUTINE); // Completion function

//BOOL bResult = WSAIoctl(s, SIO_FLUSH, NULL, 0, NULL, 0,
&dwBytesReturned, NULL, NULL);
/*if(!bResult)
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::SendPacket: Error while
FLUSH socket");*/

if (nRet != 0)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
fPending = TRUE;
}
else
{
/*AnsiString str = "--> WSASend(): ";
str += IntToStr(WSAGetLastError());*/

lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::SendPacket: Error while
sending packet %d", WSAGetLastError());

CloseHandle((HANDLE)over.hEvent);
return nRet;
}
}


// ----------------------------
// If the I/O isn't finished...
// ----------------------------
if (fPending)
{
// --------------------------------
// Wait for the request to complete
// or the exit event to be signaled
// --------------------------------
/*hEvents[0] = (HANDLE) over.hEvent;
hEvents[1] = hExit;*/
dwRet = WaitForSingleObject(over.hEvent, 60000);
/*dwRet = WaitForMultipleObjects(2,
hEvents,
FALSE,
INFINITE);*/
// ----------------------------
// Was the recv event signaled?
// ----------------------------
if (dwRet != 0)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::SendPacket:
WaitForMultipleObjects Error pending operation");
CloseHandle((HANDLE) over.hEvent);
return dwRet;
}

// --------------
// Get I/O result
// --------------
if (!WSAGetOverlappedResult(s,
&over,
&dwSent,
FALSE,
&dwFlags))
{
/*AnsiString str = "WSAGetOverlappedResult(): ";
str += IntToStr(WSAGetLastError());*/
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::SendPacket:
WSAGetOverlappedResult Error pending operation");

//form->output->Lines->Add(str);

CloseHandle((HANDLE)over.hEvent);
return -1;
}
}
*NumberOfBytesSent = dwSent;
CloseHandle((HANDLE)over.hEvent);
return TRUE;
}

//--------------------------------------------------------------

Where i'm doing wrong? Cause i can't know when i have to close the
client socket. Initially i used a sleep before closing the socket, and
everything works fine, but i know that this is very a bad solution.

Please, someone help me.

Thanks.