Проблема Http сервера C двумя клиентами

ale4ko

New Member
16.09.2007
2
0
#1
Я пишу реализацию HTTP сервера и клиента на C++.
Клиент последовательно посылает 100 запросов. Когда HTTP сервер разговаривает с одним клиентом, то он работает хорошо. Но (!!!), когда он разговаривает c двумя клиентами (запросы посылаются на разные порты), сервер получает все запросы (200 requests), но тело (body) некоторых из запросов пусто. Общение между двумя клиентами и сервером происходит на одном физическом компютере с Windows XP.

Кто-то знает, почему тело некоторых из запросов пусто?

Код клиента :

[codebox]int main (int argc, char *argv[])
{
BOOL bResults = FALSE;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;

for (int i = 1; i<=100; i++)
{
hSession = NULL;
hConnect = NULL;
hRequest = NULL;

// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);

// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"localhost",
80, 0);

// Create an HTTP Request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"POST", L"/index.html",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

// Send a Request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
"ABC", 4, 4, 0);

// Place additional code here.


// Report errors.
if (!bResults)
printf("Error %d has occurred.\n",GetLastError());

// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);

// Keep checking for data until there is nothing left.
if (bResults)
do
{

// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
printf("Error %u in WinHttpQueryDataAvailable.\n",GetLastError());

// Allocate space for the buffer.
pszOutBuffer = new char[dwSize+1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
dwSize=0;
}
else
{
// Read the Data.
ZeroMemory(pszOutBuffer, dwSize+1);

if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
printf("Error %u in WinHttpReadData.\n", GetLastError());
else
printf("%s",pszOutBuffer);

// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
}

} while (dwSize>0);

// Close open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
}

return 0;
};[/codebox]

Часть кода сервера (взятый из msdn).Я использую следующую функцию ,как listner:

[codebox]result = HttpReceiveHttpRequest(
hReqQueue,
requestId,
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
pRequest,
RequestBufferLength,
&bytesRead,
NULL
);

И каждый запрос делаeт
if(pRequest->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS)
{

if(GetTempFileName(L".\",L"New",0, szTempName) == 0)
{
result = GetLastError();
wprintf(L"GetTempFileName failed with %lu \n", result);
goto Done;
}

hTempFile = CreateFile(szTempName, GENERIC_READ | ENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if(hTempFile == INVALID_HANDLE_VALUE)
{
result = GetLastError();
wprintf(L"Could not create temporary file. Error %lu \n", result);
goto Done;
}

do
{
//
// Read the entity chunk from the request.
//
BytesRead = 0;
result = HttpReceiveRequestEntityBody(
hReqQueue,
pRequest->RequestId,
0,
pEntityBuffer,
EntityBufferLength,
&BytesRead,
NULL
);

switch(result)
{
case NO_ERROR:

if(BytesRead != 0)
{
TotalBytesRead += BytesRead;
WriteFile(
hTempFile,
pEntityBuffer,
BytesRead,
&TempFileBytesWritten,
NULL
);

}
break;

case ERROR_HANDLE_EOF:


if(BytesRead != 0)
{
TotalBytesRead += BytesRead;
WriteFile(
hTempFile,
pEntityBuffer,
BytesRead,
&TempFileBytesWritten,
NULL
);
}



StringCchPrintfA(
szContentLength,
sizeof(szContentLength),
"%lu",
TotalBytesRead
);

ADD_KNOWN_HEADER(
response,
HttpHeaderContentLength,
szContentLength
);

result =
HttpSendHttpResponse(
hReqQueue, // ReqQueueHandle
pRequest->RequestId, // Request ID
HTTP_SEND_RESPONSE_FLAG_MORE_DATA,
&response, // HTTP response
NULL, // pReserved1
&bytesSent, // bytes sent (optional)
NULL, // pReserved2
0, // Reserved3
NULL, // LPOVERLAPPED
NULL // pReserved4
);

if(result != NO_ERROR)
{
wprintf(L"HttpSendHttpResponse failed with %lu \n",
result);
goto Done;
}

//
// Send entity body from a file handle.
//
dataChunk.DataChunkType =
HttpDataChunkFromFileHandle;

dataChunk.FromFileHandle.
ByteRange.StartingOffset.QuadPart = 0;

dataChunk.FromFileHandle.
ByteRange.Length.QuadPart = HTTP_BYTE_RANGE_TO_EOF;

dataChunk.FromFileHandle.FileHandle = hTempFile;

result = HttpSendResponseEntityBody(
hReqQueue,
pRequest->RequestId,
0, // This is the last send.
1, // Entity Chunk Count.
&dataChunk,
NULL,
NULL,
0,
NULL,
NULL
);

if(result != NO_ERROR)
{
wprintf(
L"HttpSendResponseEntityBody failed with %lu \n",
result
);
}

goto Done;

break;


default:
wprintf(L"HttpReceiveRequestEntityBody failed with %lu \n",
result);
goto Done;
}

} while(TRUE);
}
else
{
// This request does not have any entity body.
//

result = HttpSendHttpResponse(
hReqQueue, // ReqQueueHandle
pRequest->RequestId, // Request ID
0,
&response, // HTTP response
NULL, // pReserved1
&bytesSent, // bytes sent (optional)
NULL, // pReserved2
0, // Reserved3
NULL, // LPOVERLAPPED
NULL // pReserved4
);
if(result != NO_ERROR)
{
wprintf(L"HttpSendHttpResponse failed with %lu \n", result);
}
}

Done:

if(pEntityBuffer)
{
FREE_MEM(pEntityBuffer);
}

if(INVALID_HANDLE_VALUE != hTempFile)
{
CloseHandle(hTempFile);
//DeleteFile(szTempName);
}

return result;
}
[/codebox]