Hello everyone.

I have a big problem using Microsoft Winsock.

The context is the follow. I need to let communicate two application
1) The client written in Java
2) The server written in Visual C++

I used the overlapped socket to create the web server, i used some code
found on the net. It seems to work, but there is a problem sending
response to client. here is the code of my CGeneriServer.cpp:

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

#include "GenericServer.h"
#include "Functions.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGenericServer::CGenericServer()
{
bRun = FALSE;
}

CGenericServer::~CGenericServer()
{

}

#define SENDBLOCK_2 400000



void CGenericServer::GetStats(StatisticsTag &st)
{
st.nTotalRecv = Stats.nTotalRecv;
st.nTotalSent = Stats.nTotalSent;
st.nTotalHits = Stats.nTotalHits;
st.nVisitors = Visitors.size();
EnterCriticalSection(&_cs);
st.nReqHighCriticalLevel = Stats.nReqHighCriticalLevel;
st.nReqMediumCriticalLevel = Stats.nReqMediumCriticalLevel;
st.nReqLowCriticalLevel = Stats.nReqLowCriticalLevel;
st.nClientsConnected = ThreadList.size();
LeaveCriticalSection(&_cs);
}



BOOL CGenericServer::AddClient(SOCKET s, char* ClientAddress, int port)
{
GotConnection(ClientAddress, port);

STRVECT::iterator it;
it = find(Visitors.begin(), Visitors.end(), ClientAddress);
if(it == Visitors.end())
Visitors.push_back(ClientAddress);

InterlockedIncrement(&Stats.nTotalHits);

ThreadTag Thread;
HANDLE hThread;
unsigned int threadID;

EnterCriticalSection(&cs);

NewConnectionTag *NewConn = (NewConnectionTag
*)malloc(sizeof(NewConnectionTag));
NewConn->pGenericServer = this;
NewConn->s = s;

hThread = CreateThread(NULL, 0, DWClientThread, NewConn, 0, (DWORD *)
&threadID);
if(hThread)
{
Thread.threadID = threadID;
Thread.hThread = hThread;
ThreadList.push_back(Thread);

}
else
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::AddClient:
_beginthreadex(...) failure");
LeaveCriticalSection(&cs);

return TRUE;
}



BOOL CGenericServer::Run(int Port, int PersTO)
{
if(bRun)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::Run:
_beginthreadex(...) failure, for Launch Thread");
return FALSE;
}

ServerPort = Port;
PersistenceTO = PersTO;

InitializeCriticalSection(&cs);
InitializeCriticalSection(&_cs);

Reset();

ThreadLaunchedEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

// Launch Accept Thread
ResetEvent(ThreadLaunchedEvent);
ThreadA = CreateThread(NULL, 0, DWAcceptThread, this, 0, (DWORD
*)&ThreadA_ID);
if(!ThreadA)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::Run:
_beginthreadex(...) failure, for Launch Thread %d",errno);
return FALSE;
}

if(WaitForSingleObject(ThreadLaunchedEvent, THREADWAIT_TO) !=
WAIT_OBJECT_0)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::Run: Unable to get
response from Accept Thread withing specified Timeout -> %d",
THREADWAIT_TO);
CloseHandle(ThreadLaunchedEvent);
return FALSE;
}

// Launch Helper Thread
ResetEvent(ThreadLaunchedEvent);
ThreadC = CreateThread(NULL, 0, DWHelperThread, this, 0, (DWORD
*)&ThreadC_ID);
if(!ThreadC)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::Run:
_beginthreadex(...) failure, for Helper Thread %d",errno);
return FALSE;
}

if(WaitForSingleObject(ThreadLaunchedEvent, THREADWAIT_TO) !=
WAIT_OBJECT_0)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::Run: Unable to get
response from Helper Thread within specified Timeout -> %d",
THREADWAIT_TO);
CloseHandle(ThreadLaunchedEvent);
return FALSE;
}

CloseHandle(ThreadLaunchedEvent);

bRun = TRUE;

return TRUE;
}



BOOL CGenericServer::Shutdown()
{
if(!bRun)
return FALSE;

BOOL bResult = TRUE;
HANDLE hArray[2];

hArray[0] = ThreadA;
hArray[1] = ThreadC;

//
// Killing Accept and Helper threads
//
SetEvent(ShutdownEvent);
DWORD n = WaitForMultipleObjects(2, hArray, TRUE, THREADKILL_TO);

if(n == WAIT_TIMEOUT || n == WAIT_FAILED)
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::Shutdown:
WaitForMultipleObjects(...) timed out");
if(!TerminateThread(ThreadA, THREADEXIT_SUCCESS))
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::Shutdown():
TerminateThread(.ThreadA.) failure, probably it is already terminated
%d", GetLastError());
if(!TerminateThread(ThreadC, THREADEXIT_SUCCESS))
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::Shutdown():
TerminateThread(.ThreadC.) failure, probably it is already terminated
%d",GetLastError());
bResult = FALSE;
}

CloseHandle(ThreadA);
CloseHandle(ThreadC);

//
// Make sure all client threads are dead
//
THREADLIST::iterator it;
while(ThreadList.size())
{
Sleep(100);
}

DeleteCriticalSection(&cs);
DeleteCriticalSection(&_cs);

bRun = FALSE;

return bResult;
}



void CGenericServer::Reset()
{
//
// Reset statistic values
//
Stats.nClientsConnected = 0;
Stats.nErrosCount = 0;
Stats.nTotalSent = 0;
Stats.nTotalRecv = 0;
Stats.nTotalHits = 0;
Stats.nVisitors = 0;
Stats.nReqHighCriticalLevel = 0;
Stats.nReqMediumCriticalLevel = 0;
Stats.nReqLowCriticalLevel = 0;
}




void CGenericServer::CleanupThread(WSAEVENT Event, SOCKET s,
NewConnectionTag* pNewConn, DWORD dwThreadID)
{
if(Event)
WSACloseEvent(Event);
closesocket(s);
EnterCriticalSection(&cs);
if(pNewConn)
{
free(pNewConn);
pNewConn = NULL;
}
LeaveCriticalSection(&cs);

THREADLIST::iterator it;
it = find_if(ThreadList.begin(), ThreadList.end(),
bind2nd(IDCompare(), dwThreadID));
if(it != ThreadList.end())
{
EnterCriticalSection(&_cs);
HANDLE aaa = (*it).hThread;
HandleList.push_back((*it).hThread);
ThreadList.erase(it);
aaa = NULL;
LeaveCriticalSection(&_cs);

}
else
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::CleanupThread: Thread
not found in the list");
}




void CGenericServer::CleanupThread(WSAEVENT Event, WSAEVENT
ShutdownEvent, SOCKET s)
{
if(Event)
WSACloseEvent(Event);

if(ShutdownEvent)
WSACloseEvent(ShutdownEvent);

if(s)
closesocket(s);

WSACleanup();
}




UINT __stdcall CGenericServer::AcceptThread(LPVOID pParam)
{
CGenericServer *pGenericServer = (CGenericServer*)pParam;
SOCKET s; // Main Listen Socket
WORD wVersionRequested;
WSADATA wsaData;
sockaddr_in saLocal;
WSAEVENT Handles[2];
WSANETWORKEVENTS NetworkEvents;
sockaddr ClientAddr;
INT addrlen = sizeof(ClientAddr);
sockaddr_in sain;
char cAddr[50];
int result;

saLocal.sin_family = AF_INET;
saLocal.sin_port = htons(pGenericServer->ServerPort);
saLocal.sin_addr.s_addr = INADDR_ANY;

wVersionRequested = MAKEWORD(2, 2);

result = WSAStartup(wVersionRequested, &wsaData);
if(result != 0)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSAStartup(...) failure %d", result);
return THREADEXIT_SUCCESS;
}

if( LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread: Requested
Socket version not exist");
pGenericServer->CleanupThread(NULL, NULL, NULL);
return THREADEXIT_SUCCESS;
}

WSAPROTOCOL_INFO tcpProtStruct;
pGenericServer->GetProtocolInfo( &tcpProtStruct);

s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,
(LPWSAPROTOCOL_INFO)&tcpProtStruct, 0, WSA_FLAG_OVERLAPPED);
if(s == INVALID_SOCKET)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSASocket(...) failure %d", WSAGetLastError());
pGenericServer->CleanupThread(NULL, NULL, NULL);
return THREADEXIT_SUCCESS;
}

//
// B I N D
//
result = bind(s, (struct sockaddr *)&saLocal, sizeof(saLocal));
if(result == SOCKET_ERROR)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread: bind(...)
failure %d",WSAGetLastError());
pGenericServer->CleanupThread(NULL, NULL, s);
return THREADEXIT_SUCCESS;
}

//
// L I S T E N
//
result = listen(s, SOMAXCONN);
if(result == SOCKET_ERROR)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread: listen(...)
failure %d", WSAGetLastError());
pGenericServer->CleanupThread(NULL, NULL, s);
return THREADEXIT_SUCCESS;
}

pGenericServer->ShutdownEvent = WSACreateEvent();
if(pGenericServer->ShutdownEvent == WSA_INVALID_EVENT)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSACreateEvent(...) failure for ShutdownEvent %d",WSAGetLastError());
pGenericServer->CleanupThread(NULL, NULL, NULL, s);
return THREADEXIT_SUCCESS;
}

WSAEVENT Event = WSACreateEvent();
if(Event == WSA_INVALID_EVENT)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSACreateEvent(...) failure for Event %d",WSAGetLastError());
pGenericServer->CleanupThread(NULL, pGenericServer->ShutdownEvent,
s);
return THREADEXIT_SUCCESS;
}

Handles[0] = pGenericServer->ShutdownEvent;
Handles[1] = Event;

result = WSAEventSelect(s, Event, FD_ACCEPT);
if(result == SOCKET_ERROR)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSAEventSelect(...) failure %d", WSAGetLastError());
pGenericServer->CleanupThread(Event, pGenericServer->ShutdownEvent,
s);
return THREADEXIT_SUCCESS;
}

SetEvent(pGenericServer->ThreadLaunchedEvent);

for(;
{
DWORD EventCaused = WSAWaitForMultipleEvents(
2,
Handles,
FALSE,
WSA_INFINITE,
FALSE);

if(EventCaused == WAIT_FAILED || EventCaused == WAIT_OBJECT_0)
{
if(EventCaused == WAIT_FAILED)
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WaitForMultipleObjects(...) failure %d", GetLastError());
pGenericServer->CleanupThread(Event, pGenericServer->ShutdownEvent,
s);
return THREADEXIT_SUCCESS;
}

result = WSAEnumNetworkEvents(
s,
Event,
&NetworkEvents);

if(result == SOCKET_ERROR)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSAEnumNetworkEvents(...) failure %d", WSAGetLastError());
pGenericServer->CleanupThread(Event, pGenericServer->ShutdownEvent,
s);
return THREADEXIT_SUCCESS;
}

if(NetworkEvents.lNetworkEvents == FD_ACCEPT)
{
SOCKET ClientSocket = WSAAccept(s, &ClientAddr, &addrlen, NULL,
NULL);
memcpy(&sain, &ClientAddr, addrlen);
sprintf(cAddr, "%d.%d.%d.%d",
sain.sin_addr.S_un.S_un_b.s_b1,
sain.sin_addr.S_un.S_un_b.s_b2,
sain.sin_addr.S_un.S_un_b.s_b3,
sain.sin_addr.S_un.S_un_b.s_b4);

if(INVALID_SOCKET == ClientSocket)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
WSAAccept(...) failure %d", WSAGetLastError());
// I think there is no reason to shutdown whole server if just one
connection failed
continue;
}
else
{
if(!pGenericServer->AddClient(ClientSocket, cAddr, sain.sin_port))
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread:
AddClient(...) failure", "AcceptThread");
continue; // I think there is no reason to shutdown whole server
if just one connection failed
}
}
}
else
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::AcceptThread: Unknown
Event %d", NetworkEvents.lNetworkEvents);
continue;
}


}

pGenericServer->CleanupThread(Event, pGenericServer->ShutdownEvent,
s);
return THREADEXIT_SUCCESS;
}




DWORD WINAPI CGenericServer:WAcceptThread(LPVOID pParam)
{
return (DWORD) AcceptThread(pParam);
}

DWORD WINAPI CGenericServer:WClientThread(LPVOID pParam)
{
return (DWORD) ClientThread(pParam);
}

DWORD WINAPI CGenericServer:WHelperThread(LPVOID pParam)
{
return (DWORD) HelperThread(pParam);
}

unsigned __stdcall CGenericServer::ClientThread(LPVOID pParam)
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: ---> Network
Event Occured...");

NewConnectionTag *pNewConn = (NewConnectionTag*)pParam;
CGenericServer *pGenericServer = pNewConn->pGenericServer;
SOCKET s = pNewConn->s;

int result;
WSAEVENT EventArray[2];
WSANETWORKEVENTS NetworkEvents;

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

WSAEVENT Event = WSACreateEvent();

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

pRequest->user = getRemoteUser(s);

if(Event == WSA_INVALID_EVENT)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::ClientThread:
WSACreateEvent(...) failure %d", WSAGetLastError());
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

result = WSAEventSelect(s, Event, FD_READ | FD_WRITE | FD_CLOSE);
if(result == SOCKET_ERROR)
{
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::ClientThread:
WSAEventSelect(...) failure %d", WSAGetLastError());
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(), pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

EventArray[0] = Event;
EventArray[1] = pGenericServer->ShutdownEvent;

for(;
{
DWORD EventCaused = WSAWaitForMultipleEvents(
2,
EventArray,
FALSE,
pGenericServer->PersistenceTO ? pGenericServer->PersistenceTO :
WSA_INFINITE,
FALSE);

if(WSA_WAIT_FAILED == EventCaused)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ClientThread:
WSAWaitForMultipleEvents(...) failure %d", WSAGetLastError());
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(), pRequest, pResponse );
return THREADEXIT_SUCCESS;
}

//
// Check if our Server mission is over or Client established
connection, but no request so far
//
if(EventCaused == 1 || EventCaused == WSA_WAIT_TIMEOUT)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ClientThread:
WSA_WAIT_TIMEOUT Event occurred");
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(),pRequest , pResponse);

return THREADEXIT_SUCCESS;
}

//
// Determine which network event occured
//
result = WSAEnumNetworkEvents(
s,
Event,
&NetworkEvents);

if(result == SOCKET_ERROR)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ClientThread:
WSAEnumNetworkEvents(...) failure %d", WSAGetLastError());
continue;
}

//
// No idea where zero came from...
//
if(!NetworkEvents.lNetworkEvents)

continue;

//
// Process Events
//
if(NetworkEvents.lNetworkEvents & FD_READ)
{
lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Read
Network event" );
//
// Do not collect Incomming data, just pass it away to inherited
class
//
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))
continue;

//char ** strResponse = (char **)malloc(sizeof(char*));
//memset(strResponse,0,bufferlenght);
//int bufferlenght = 0;

//Parsing Request
if(!pGenericServer->ParseRequest(pRequest))
{
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

//Perform Request
if(!pGenericServer->PerformeRequest(pRequest, pResponse))
{
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

//
// Send Response to client
//

NumberOfBytesSent = 0;
dwBytesSent = 0;
bSendHeader = TRUE;

iTotalResponseSize = strlen(pResponse->szResponseHeader) +
pResponse->iBufferLenght;
//Send Header

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;
//if(sResponseBuffer)
// free(sResponseBuffer);
sResponseBuffer = (char *)malloc(sizeof(char) * iPacketLength);
memcpy(sResponseBuffer, pResponse->szResponseHeader,
strlen(pResponse->szResponseHeader));
memcpy(&sResponseBuffer[strlen(pResponse->szResponseHeader)],
pResponse->response, pResponse->iBufferLenght);

/*result = CGenericServer::SendPacket(s,
sResponseBuffer,
iPacketLength,
&NumberOfBytesSent,
pGenericServer->ShutdownEvent);

if(SOCKET_ERROR != result)
{
dwBytesSent += NumberOfBytesSent;
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ClientThread: Response
Size: %ld", iPacketLength);
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ClientThread: Response
sent: %d", NumberOfBytesSent);

}*/

do
{
result = SendPacket(s,
&sResponseBuffer[dwBytesSent],
((iPacketLength - dwBytesSent) >= SENDBLOCK) ? SENDBLOCK :
(iPacketLength - dwBytesSent),
&NumberOfBytesSent,
pGenericServer->ShutdownEvent);
//Send Header
//if(bSendHeader && dwBytesSent <
strlen(pResponse->szResponseHeader))
//{
//
// result = CGenericServer::SendPacket(s,
// (char *)&(pResponse->szResponseHeader[dwBytesSent]),
// (strlen(pResponse->szResponseHeader) - dwBytesSent) >=
SENDBLOCK_2 ? SENDBLOCK_2 : strlen(pResponse->szResponseHeader) -
dwBytesSent,
// &NumberOfBytesSent,
// pGenericServer->ShutdownEvent);
//}
////Send Body
//else {

// //lg.Log(DV_LOG_LEVEL_DEBUG, "prima di WSASend. Buffer len: %d
bytes di %d bytes, byte to send : %d", Buffer.len, bufferlenght,
bufferlenght - dwBytesSent);
// result = CGenericServer::SendPacket(s,
// &(pResponse->response[dwBytesSent -
strlen(pResponse->szResponseHeader)]),
// (pResponse->iBufferLenght -
(dwBytesSent - strlen(pResponse->szResponseHeader))) >= SENDBLOCK_2 ?
// SENDBLOCK_2 :
// pResponse->iBufferLenght - (dwBytesSent -
strlen(pResponse->szResponseHeader)),
// &NumberOfBytesSent,
// pGenericServer->ShutdownEvent);
//}

lg.Log(DV_LOG_LEVEL_DEBUG, "dopo di WSASend. NumberOfBytesSent:
%d", NumberOfBytesSent);

if(SOCKET_ERROR != result)
{
dwBytesSent += NumberOfBytesSent;

if(bSendHeader && dwBytesSent >=
strlen(pResponse->szResponseHeader))
bSendHeader = FALSE;
}
}
while((dwBytesSent < iTotalResponseSize) && SOCKET_ERROR !=
result);

if(WSAGetLastError() == WSAEWOULDBLOCK)
{
bResend = TRUE;
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: Error
WSASend: WSAEWOULDBLOCK" );
continue;
}

//


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



if(!bKeepAlive)
{
/*lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Byte
sent: %ld", dwBytesSent);*/

lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Thread
exit, cause not keepAlived connection (FD_READ).");
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(),pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

//
// We are finished with this request, clear buffer for next one
//
}
else
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::ClientThread:
WSARecv(...) failure %d", WSAGetLastError());
}


if((NetworkEvents.lNetworkEvents & FD_WRITE) && bResend)
{

lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Write
Network event" );
//
// Send Response to client
//

/*result = CGenericServer::SendPacket(s,
(char *)&(sResponseBuffer [dwBytesSent]),
(iPacketLength - dwBytesSent),
&NumberOfBytesSent,
pGenericServer->ShutdownEvent);

if(SOCKET_ERROR != result) {
dwBytesSent += NumberOfBytesSent;
}*/

do
{
result = SendPacket(s,
&sResponseBuffer[dwBytesSent],
((iPacketLength - dwBytesSent) >= SENDBLOCK) ? SENDBLOCK :
(iPacketLength - dwBytesSent),
&NumberOfBytesSent,
pGenericServer->ShutdownEvent);
////Send Header
//if(bSendHeader && dwBytesSent <
strlen(pResponse->szResponseHeader))
//{
//
// result = CGenericServer::SendPacket(s,
// (char *)&(pResponse->szResponseHeader [dwBytesSent]),
// (strlen(pResponse->szResponseHeader) - dwBytesSent) >=
SENDBLOCK_2 ? SENDBLOCK_2 : strlen(pResponse->szResponseHeader) -
dwBytesSent,
// &NumberOfBytesSent,
// pGenericServer->ShutdownEvent);
//}
////Send Body
//else {
// result = CGenericServer::SendPacket(s,
//
&(pResponse->response[dwBytesSent -
strlen(pResponse->szResponseHeader)]),
// (pResponse->iBufferLenght -
(dwBytesSent - strlen(pResponse->szResponseHeader))) >= SENDBLOCK_2 ?
// SENDBLOCK_2 :
// pResponse->iBufferLenght - (dwBytesSent -
strlen(pResponse->szResponseHeader)),
// &NumberOfBytesSent,
// pGenericServer->ShutdownEvent);
//}

//lg.Log(DV_LOG_LEVEL_DEBUG, "dopo di WSASend. NumberOfBytesSent:
%d", NumberOfBytesSent);

/*lg.Log(DV_LOG_LEVEL_DEBUG, "prima flush");
result = WSAIoctl(s, SIO_FLUSH, Buffer.buf, Buffer.len, NULL, 0,
&NumberOfBytesSent, NULL, NULL);
lg.Log(DV_LOG_LEVEL_DEBUG, "dopo flush");*/

if(SOCKET_ERROR != result) {
dwBytesSent += NumberOfBytesSent;
}


}
while((dwBytesSent < iTotalResponseSize) && SOCKET_ERROR != result);

if(WSAGetLastError() == WSAEWOULDBLOCK)
{
bResend = TRUE;
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: Error
WSASend: WSAEWOULDBLOCK" );
continue;
}

/*lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: Total
Data Sent: %ld", dwBytesSent);*/

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

//
// We are finished with this request, clear the buffer for next one
//
if(!bKeepAlive)
{
lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::ClientThread: Thread
exit, cause not keepAlived connection (FD_WRITE).");
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(), pRequest, pResponse);
return THREADEXIT_SUCCESS;
}

bResend = FALSE;
}

if(NetworkEvents.lNetworkEvents & FD_CLOSE)
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread: WSA CLOSE
EVENT occurred");
if(sResponseBuffer)
free(sResponseBuffer);
pGenericServer->CleanupThread(Event, s, pNewConn,
GetCurrentThreadId(), pRequest, pResponse);
return THREADEXIT_SUCCESS;
}
}

lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::ClientThread:
THREADEXIT_SUCCESS");
return THREADEXIT_SUCCESS; // We never reach this point
}


UINT __stdcall CGenericServer::HelperThread(LPVOID pParam)
{
CGenericServer *pGenericServer = (CGenericServer*)pParam;
HANDLELIST::iterator it;

SetEvent(pGenericServer->ThreadLaunchedEvent);

for(;
{
if(WaitForSingleObject(pGenericServer->ShutdownEvent, TICK) ==
WAIT_TIMEOUT)
{
EnterCriticalSection(&pGenericServer->_cs);
while(pGenericServer->HandleList.size())
{
HANDLE h = pGenericServer->HandleList.front();
DWORD n = WaitForSingleObject(h, THREADKILL_TO);
if(n == WAIT_TIMEOUT)
{
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::HelperThread:
WaitForSingleObject(...) timed out");
if(!TerminateThread(h, THREADEXIT_SUCCESS))
lg.Log(DV_LOG_LEVEL_DEBUG, "CGenericServer::HelperThread:
TerminateThread(.h.) failure, probably it is already terminated %d",
GetLastError());
}
CloseHandle(h);
pGenericServer->HandleList.pop_front();
}
LeaveCriticalSection(&pGenericServer->_cs);
}
else
return THREADEXIT_SUCCESS;

}

return THREADEXIT_SUCCESS;
}


DIGIVISION::User * getRemoteUser(SOCKET s) {

struct sockaddr_in remote_addr;
int dim = sizeof(remote_addr);

// determina le impostazioni dell'host remoto

if(getpeername(s, (struct sockaddr *)&remote_addr,
&dim)==SOCKET_ERROR)
{
//FormatError ("SetSocketHandle(getpeername)", WSAGetLastError());

// --- EXCEPTON:
//except.Raise(err_msg,__FILE__,__LINE__);

return NULL;
}

DIGIVISION::User * remoteUser = new DIGIVISION::User();

remoteUser->setIP(inet_ntoa(remote_addr.sin_addr));
remoteUser->setPort((int)remote_addr.sin_port);

return remoteUser;

}


void CGenericServer::CleanupThread(WSAEVENT Event, SOCKET s,
NewConnectionTag* pNewConn, DWORD dwThreadID, WSRequest * pWSRequest,
WSResponse * pWSResponse)
{
lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::CleanupThread: Free request
and response");

if(pWSRequest->iState == EXECUTING_REQUEST_STATE)
DecreaseRequestStats(pWSRequest->getCriticalLevel());

delete pWSRequest;
delete pWSResponse;

pWSRequest = NULL;
pWSResponse = NULL;

//DEALLOC_POINTER(pWSRequest, WSRequest, Functions:ELETE_OPERATOR);
//DEALLOC_POINTER(pWSResponse, WSResponse,
Functions:ELETE_OPERATOR);

lg.Log(DV_LOG_LEVEL_DEBUG,"CGenericServer::CleanupThread: Clean Event
& socket connection" );
CleanupThread(Event, s,pNewConn,dwThreadID);
}



BOOL CGenericServer::CheckPerformRequest(WSRequest * pWSRequest)
{

BOOL bPerform = TRUE;

StatisticsTag st;
GetStats(st);

if( (st.nReqHighCriticalLevel + st.nReqMediumCriticalLevel +
st.nReqLowCriticalLevel) == MAX_CONNECTION_NUMBER)
{
bPerform = FALSE;
lg.Log(DV_LOG_LEVEL_INFO, "CGenericServer::CheckPerformRequest:
Maximun connection number exceeded: %d", MAX_CONNECTION_NUMBER);
}
else {
switch(pWSRequest->getCriticalLevel())
{
case CRITICAL_LEVEL_HIGH:
if(N_REQ_CRITICAL_LEVEL_HIGH <= st.nReqHighCriticalLevel)
{
lg.Log(DV_LOG_LEVEL_INFO, "CGenericServer::CheckPerformRequest:
Maximun High Critical Level Request Number exceeded: %d",
N_REQ_CRITICAL_LEVEL_HIGH);
bPerform = FALSE;
}
break;
case CRITICAL_LEVEL_MEDIUM:
if(N_REQ_CRITICAL_LEVEL_MEDIUM <= st.nReqMediumCriticalLevel)
{
lg.Log(DV_LOG_LEVEL_INFO, "CGenericServer::CheckPerformRequest:
Maximun Medium Critical Level Request Number exceeded: %d",
N_REQ_CRITICAL_LEVEL_HIGH);
bPerform = FALSE;
}
break;
case CRITICAL_LEVEL_LOW:
if(N_REQ_CRITICAL_LEVEL_LOW <= st.nReqMediumCriticalLevel)
{
lg.Log(DV_LOG_LEVEL_INFO, "CGenericServer::CheckPerformRequest:
Maximun Low Critical Level Request Number exceeded: %d",
N_REQ_CRITICAL_LEVEL_HIGH);
bPerform = FALSE;
}
break;
default:
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::CheckPerformRequest:
Unknown Critical Level Request: %d",
pWSRequest->getCriticalLevel());
}
}

if(bPerform)
{
IncreaseRequestStats(pWSRequest->getCriticalLevel());
pWSRequest->iState = EXECUTING_REQUEST_STATE;
}

return bPerform;
}

void CGenericServer::IncreaseRequestStats(int iCriticalLevel)
{
EnterCriticalSection(&_cs);

switch(iCriticalLevel)
{
case CRITICAL_LEVEL_HIGH:
Stats.nReqHighCriticalLevel++;
break;
case CRITICAL_LEVEL_MEDIUM:
Stats.nReqMediumCriticalLevel++ ;
break;
case CRITICAL_LEVEL_LOW:
Stats.nReqLowCriticalLevel++;
break;
default:
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer::CleanupThread: Unknown
critical level : %d", iCriticalLevel);
}

LeaveCriticalSection(&_cs);
}


void CGenericServer:ecreaseRequestStats(int iCriticalLevel)
{
EnterCriticalSection(&_cs);

switch(iCriticalLevel)
{
case CRITICAL_LEVEL_HIGH:
if(Stats.nReqHighCriticalLevel>0)
Stats.nReqHighCriticalLevel--;
else
lg.Log(DV_LOG_LEVEL_WARNING,"CGenericServer:ecreaseRequestStats:
Not allowed decreasing of Stats.nReqHighCriticalLevel, cause = 0");
break;
case CRITICAL_LEVEL_MEDIUM:
if(Stats.nReqMediumCriticalLevel>0)
Stats.nReqMediumCriticalLevel--;
else
lg.Log(DV_LOG_LEVEL_WARNING,"CGenericServer:ecreaseRequestStats:
Not allowed decreasing of Stats.nReqMediumCriticalLevel, cause = 0");
break;
case CRITICAL_LEVEL_LOW:
if(Stats.nReqLowCriticalLevel>0)
Stats.nReqLowCriticalLevel--;
else
lg.Log(DV_LOG_LEVEL_WARNING,"CGenericServer:ecreaseRequestStats:
Not allowed decreasing of Stats.nReqLowCriticalLevel, cause = 0");
break;
default:
lg.Log(DV_LOG_LEVEL_WARNING, "CGenericServer:ecreaseRequestStats:
Unknown critical level request: %d", iCriticalLevel);
}

LeaveCriticalSection(&_cs);
}

int CGenericServer::ReceivePacket(SOCKET s, char * packetRead, DWORD
MaxByteToRead ,DWORD * NumberOfBytesReceived)
{
WSABUF * pBuffer = (WSABUF *)malloc(sizeof(WSABUF)) ;
pBuffer->buf = packetRead;
pBuffer->len = MaxByteToRead;
DWORD Flags = 0;

int result = WSARecv(s,
pBuffer,
1,
NumberOfBytesReceived,
&Flags,
NULL,
NULL);

free(pBuffer);

return result;
}



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_ERROR, "CGenericServer::ReceivePacket: Operation
pending...");

hEvents[0] = (HANDLE)over.hEvent;
hEvents[1] = hExit;
dwRet = WaitForMultipleObjects(2,
hEvents,
FALSE,
INFINITE);
// ----------------------------
// Was the recv event signaled?
// ----------------------------
if (dwRet != 0)
{
lg.Log(DV_LOG_LEVEL_ERROR, "CGenericServer::ReceivePacket: dwRet in
RecvRequest()");
//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 * packetToSend, int
iPacketLenght, DWORD * NumberOfBytesSent)
{
WSABUF * pBuffer = (WSABUF *) malloc(sizeof(WSABUF));

pBuffer->len = iPacketLenght;
pBuffer->buf = packetToSend;

//lg.Log(DV_LOG_LEVEL_DEBUG, "prima di WSASend. Buffer len: %d bytes
di %d bytes, byte to send : %d", Buffer.len, bufferlenght, bufferlenght
- dwBytesSent);

int result = WSASend(s,
pBuffer,
1,
NumberOfBytesSent,
0,
NULL,
NULL);

free(pBuffer);

return result;

//lg.Log(DV_LOG_LEVEL_DEBUG, "dopo di WSASend. NumberOfBytesSent: %d",
NumberOfBytesSent);

/*lg.Log(DV_LOG_LEVEL_DEBUG, "prima flush");
result = WSAIoctl(s, SIO_FLUSH, Buffer.buf, Buffer.len, NULL, 0,
&NumberOfBytesSent, NULL, NULL);
lg.Log(DV_LOG_LEVEL_DEBUG, "dopo flush");*/
}

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));

wsabuf.buf = pBuf;
wsabuf.len = iPacketLenght;
over.hEvent = WSACreateEvent();

fPending = FALSE;
nRet = WSASend(s, // Socket
&wsabuf, // WSABUF
1, // Number of buffers
&dwSent, // Bytes sent
0, // Flags
&over, // WSAOVERLAPPED
NULL); // 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;
}

void CGenericServer::GetProtocolInfo(WSAPROTOCOL_INFO *
lpTcpProtStruct)
{

DWORD dwBufLen;
DWORD dwErr;
WSAPROTOCOL_INFO * lpProtocolBuf = NULL;
BOOL bProtocolFound;
// First, have WSAEnumProtocols tell you how big a buffer you need.
int nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
if (SOCKET_ERROR != nRet)
printf("WSAEnumProtocols: should not have succeeded\n");
else if (WSAENOBUFS != (dwErr = WSAGetLastError()))
// WSAEnumProtocols failed for some reason not relating to buffer
// size - also odd.
printf("WSAEnumProtocols(1): %d\n", WSAGetLastError());
else
{
// WSAEnumProtocols failed for the "expected" reason. Therefore,
// you need to allocate a buffer of the appropriate size.
if(!lpProtocolBuf)
lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen);
if (lpProtocolBuf)
{
// Now you can call WSAEnumProtocols again with the expectation
// that it will succeed because you have allocated a big enough
// buffer.
nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
if (SOCKET_ERROR == nRet)
printf("WSAEnumProtocols(3): %d\n", WSAGetLastError());
else
{
// Loop through protocols, looking for the first service
// provider that meets the matching criteria.
bProtocolFound = FALSE;
for (int i=0; i {
if ((IPPROTO_TCP == lpProtocolBuf[i].iProtocol) &&
(XP1_QOS_SUPPORTED == (XP1_QOS_SUPPORTED &
lpProtocolBuf[i].dwServiceFlags1)))
{
memcpy(lpTcpProtStruct, &lpProtocolBuf[i],
sizeof(WSAPROTOCOL_INFO));
bProtocolFound = TRUE;
break;
}
}
}
}
}

if(lpProtocolBuf)
free(lpProtocolBuf);

}




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



The problem is in the SendPacket, cause even though the WSASend and the
other function tell me that all operation was fine, before the client
read entire response, it goes in exception because the server close the
connection, here is the java stacktrace

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream. java:168)
at java.io.BufferedInputStream.fill(BufferedInputStre am.java:183)
at java.io.BufferedInputStream.read1(BufferedInputStr eam.java:222)
at java.io.BufferedInputStream.read(BufferedInputStre am.java:277)
at sun.net.www.MeteredStream.read(MeteredStream.java:65)
at java.io.FilterInputStream.read(FilterInputStream.j ava:111)
at
sun.nio.cs.StreamDecoder$CharsetSD.readBytes(Strea mDecoder.java:406)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(Stream Decoder.java:446)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:1 80)
at java.io.InputStreamReader.read(InputStreamReader.j ava:167)
at java.io.BufferedReader.fill(BufferedReader.java:13 6)
at java.io.BufferedReader.readLine(BufferedReader.jav a:299)
at java.io.BufferedReader.readLine(BufferedReader.jav a:362)
at digivision.server.test.XMLRequestor.main(XMLReques tor.java:158)


Someone can help me to understand what happen? Why the server doen't
check if the client has received all packet? How can fix the situation?

Please help me. Thank you.