2025-04-27 07:49:33 -04:00

561 lines
16 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
client.c
Abstract:
Simple client app to pump new bytes to server.
Format : 0123456789012345678....
Author:
Stanle Tam (stanleyt) 4-June 1997
Revision History:
--*/
#include "client.h"
BOOL StartClients()
{
DWORD rgdwThreadId[MAX_THREADS];
TCHAR szMsg[MAX_PATH] = _T("");
BOOL fReturn = FALSE;
UINT i;
for (i = 0; i < g_nThread ; i++) {
g_rghThreads[i] =
CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)&SendData,
(LPVOID)i, // local thread id
0,
&rgdwThreadId[i] );
if (INVALID_HANDLE_VALUE == g_rghThreads[i]) {
wsprintf(szMsg, "Failed to start Client [%2d] ! Error =%d\n", i, GetLastError());
printf(szMsg);
return fReturn;
} else {
wsprintf(szMsg, "Client [%d] started to run ....\n", i);
printf(szMsg);
}
}
fReturn = TRUE;
return fReturn ;
}
void TerminateClients()
{
UINT i;
TCHAR szMsg[MAX_PATH] = _T("");
if ( WAIT_FAILED == WaitForMultipleObjects( g_nThread ,
g_rghThreads,
TRUE,
INFINITE) ) {
wsprintf(szMsg, "WaitForMultipleObjects Failed. Error = %d\n", GetLastError() );
}
for (i = 0; i < g_nThread ; ++i) {
CloseHandle(g_rghThreads[i]);
wsprintf(szMsg, "Terminating Client [%d].. \n", i);
printf(szMsg);
}
wsprintf(szMsg, "%d Client(s) are closed\n", g_nThread );
printf(szMsg);
return;
}
BOOL WINAPI SendData(UINT uThreadID)
{
BOOL fReturn = TRUE;
DWORD cLoop = g_cLoop;
DWORD cTimes = 0;
//
// ToDo : Need to rewrite this routine to make it stop
// itself automically based on the number of minutes to run
//
assert (uThreadID < MAX_THREADS);
while ( cLoop--) {
fReturn = SendRequest( uThreadID);
if (FALSE == fReturn)
break;
printf("Client [%d] finish %d time(s)..\n\n", uThreadID, ++cTimes);
}
return fReturn;
}
BOOL SendRequest(UINT uThreadID)
{
HINTERNET hOpen, hConnect, hRequest;
DWORD cbQueryReturnByte = MAX_DATA_LENGTH;
CHAR szQueryBuf[MAX_DATA_LENGTH] = {0};
TCHAR szMsg[MAX_DATA_LENGTH] = _T("");
LPBYTE pbSendRequestData;
BOOL fReturn = FALSE;
UINT i;
__try {
if (g_cbSendRequestLength) {
pbSendRequestData = (LPBYTE)LocalAlloc(0, g_cbSendRequestLength);
if (NULL == pbSendRequestData ) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
printf("Not Enough Memory. Can't send Request..");
__leave;
} else {
//
// Stuff bytes - format : 0123456789012345678....
//
for (i = 0; i < g_cbSendRequestLength; i++)
pbSendRequestData[i] = i % 10 + '0';
}
}
hOpen =
InternetOpen(g_szTestType,
INTERNET_OPEN_TYPE_DIRECT,
NULL,
NULL,
0);
if (NULL == hOpen) {
wsprintf(szMsg, "Failed on InternetOpen returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
hConnect =
InternetConnect(hOpen,
g_szServerName,
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
0);
if (NULL == hConnect) {
wsprintf(szMsg, "Failed on InternetConnect returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
hRequest =
HttpOpenRequest(hConnect,
g_szVerb,
g_szObject,
NULL,
NULL,
NULL,
dwDefaultFlag,
0);
if (NULL == hRequest) {
wsprintf(szMsg, "Failed on HttpOpenRequest returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
fReturn =
HttpAddRequestHeaders( hRequest,
g_szRequestString,
//strlen(g_szRequestString), // -1L,
-1L,
0);
if (FALSE == fReturn) {
wsprintf(szMsg, "Failed on HttpAddRequestHeaders returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
fReturn =
HttpSendRequest(hRequest,
NULL,
0,
pbSendRequestData,
g_cbSendRequestLength);
if (FALSE == fReturn) {
wsprintf(szMsg, "Failed on HttpSendRequest returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
fReturn =
HttpQueryInfo( hRequest,
HTTP_QUERY_RAW_HEADERS_CRLF,
szQueryBuf,
&cbQueryReturnByte,
NULL);
if (FALSE == fReturn) {
wsprintf(szMsg, "Failed on HttpQueryInfo returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
wsprintf(szMsg, "HttpQueryInfo returns buffer .. %s\n", szQueryBuf);
printf(szMsg);
if (!_tcsicmp(g_szTestType, "TF") ||
!_tcsicmp(g_szTestType, "WC") ||
!_tcsicmp(g_szTestType, "RC") ||
!_tcsicmp(g_szTestType, "AWC") ||
!_tcsicmp(g_szTestType, "ARC") ||
!_tcsicmp(g_szTestType, "SSF")) {
//
// Length will be whatever specified in the query string for
// write client and transmit file, MAX_DATA_LENGTH for now.
//
CHAR szReadFileBuf[MAX_DATA_LENGTH] = {0};
DWORD cbReadFileByte = MAX_DATA_LENGTH;
DWORD cbReadFileReturnByte = 0;
fReturn =
InternetReadFile(hRequest,
szReadFileBuf,
cbReadFileByte,
&cbReadFileReturnByte);
if (FALSE == fReturn) {
wsprintf(szMsg, "Failed on InternetReadFile returns %d\n", GetLastError());
printf(szMsg);
__leave;
}
//
// Create a file to store the body sent from Server. Output file is
// placed under the TEMP directory with a file name ISAPI<index>.cmp
// where <index> represents the thread number it belongs.
// Also output the body to the screen.
//
wsprintf(szMsg, "InternetReadFile returns :\n%s\n", szReadFileBuf);
printf(szMsg);
if ( FALSE == CreateReadInternetFile(uThreadID, szReadFileBuf, cbReadFileReturnByte)) {
__leave;
}
}
fReturn = TRUE;
}
__finally {
if ( hOpen != NULL) {
InternetCloseHandle(hOpen);
hOpen = NULL;
}
if ( ! g_fEatMemory)
LocalFree(pbSendRequestData);
}
return fReturn;
}
BOOL ParseArguments(INT argc, char *argv[], UINT *TestType)
{
PCHAR pChar = NULL;
BOOL fRet = TRUE;
if ((argc == 1)) {
return (FALSE);
}
while (--argc)
{
pChar = *++argv;
if (*pChar == '-' || *pChar == '/') {
while (*++pChar) {
switch (tolower(*pChar)) {
case 's': // server name
if (--argc == 0)
return (FALSE);
argv++;
_tcscpy(g_szServerName, *argv);
break;
case 't': // test type
if (--argc == 0)
return (FALSE);
argv++;
_tcscpy(g_szTestType, *argv);
break;
case 'p': // Virtual Path
if (--argc == 0)
return (FALSE);
argv++;
_tcscpy(g_szVrPath, *argv);
/*FixFileName(*argv);*/
break;
case 'h': // thread number
if (--argc == 0)
return (FALSE);
argv++;
g_nThread = atoi(*argv);
if (g_nThread < 1)
g_nThread = 1;
break;
case 'b': // Send Byte Count
if (--argc == 0)
return FALSE;
argv++;
_tcscpy(g_szByteCount, *argv);
break;
case 'c': // Loop count per thread
if (--argc == 0)
return FALSE;
argv++;
g_cLoop = atoi(*argv);
break;
case 'e': // Eat memory on purpose
if (--argc == 0)
return FALSE;
argv++;
g_fEatMemory = ( atoi(*argv) == 0 ? FALSE : TRUE);
break;
case 'k': // Keep Connection Alive
if (--argc == 0)
return FALSE;
argv++;
if ( atoi(*argv) == 1 )
dwDefaultFlag |= INTERNET_FLAG_KEEP_CONNECTION ;
break;
default:
return (FALSE);
}
}
} else {
return (FALSE);
}
}
if (!_tcscmp(g_szServerName, "") ||
!_tcscmp(g_szTestType, "") ||
!_tcscmp(g_szVrPath, "") )
return (FALSE);
//
// determine request string
//
*TestType = 0;
while (_tcscmp(rgTestType[*TestType], "bad_type") || *TestType < BAD) {
if (!_tcsicmp(rgTestType[*TestType], g_szTestType))
break;
(*TestType)++;
}
return (*TestType == BAD ? FALSE : TRUE);
}
BOOL ProcessArguments(const UINT TestType)
{
BOOL fReturn = TRUE;
switch (TestType)
{
case TF:
// add TransmitFile test
break;
case RC:
// Async ReadClient()
if ( _tcscmp(g_szByteCount, "")) {
g_cbSendRequestLength = (DWORD)atol(g_szByteCount);
wsprintf(g_szObject, "%s?SYNC", g_szVrPath);
wsprintf(g_szRequestString, "Content-Length: %s\r\n\r\n", g_szByteCount);
break;
} else
fReturn = FALSE;
break;
case WC:
// add WriteClient test
break;
case AWC:
// add Async WriteClient test
break;
case ARC:
// Async ReadClient()
if ( _tcscmp(g_szByteCount, "")) {
g_cbSendRequestLength = (DWORD)atol(g_szByteCount);
wsprintf(g_szObject, "%s?ASYNC", g_szVrPath);
wsprintf(g_szRequestString, "Content-Length: %s\r\n\r\n", g_szByteCount);
break;
} else {
fReturn = FALSE;
break;
}
case SSF:
// ServerSupportFunction()
wsprintf(g_szObject, "%s?Keep_Alive", g_szVrPath);
strcat(g_szRequestString, "\r\n\r\n");
break;
default: // bad_type
fReturn = FALSE;
}
return fReturn;
}
void FixFileName(char *argv)
{
UINT uS = 0,
uD = 0,
uLen = strlen(argv);
while (uS < uLen)
{
if (argv[uS] == '\\')
g_szFileName[uD++] = '\\';
g_szFileName[uD++] = argv[uS++];
}
g_szFileName[uD] = '\0';
}
BOOL CreateReadInternetFile(const UINT uThreadID,
const char* szReadFileBuf,
const DWORD cbReadFileByte)
{
BOOL fReturn = FALSE;
HANDLE g_hLogFile = INVALID_HANDLE_VALUE;
CHAR szFileIndx[10] = {0};
CHAR szFileName[100] = "c:\\temp\\ISAPI";
_itoa (uThreadID, szFileIndx, 10);
_tcscat(szFileName, szFileIndx);
_tcscat(szFileName, ".cmp"); // extension cmp for comparion
__try {
BOOL fOK;
DWORD cbWritten = 0;
g_hLogFile =
CreateFile( (LPCTSTR)szFileName,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
0,
NULL);
if ( INVALID_HANDLE_VALUE == g_hLogFile) {
__leave;
}
if ( 0xFFFFFFFF == SetFilePointer( g_hLogFile, 0, NULL, FILE_END) ) {
__leave;
}
fOK = WriteFile( g_hLogFile,
szReadFileBuf,
cbReadFileByte,
&cbWritten,
NULL);
if (!fOK || 0 == cbWritten) {
__leave;
}
fReturn = TRUE;
}
__finally { // clean up
if ( g_hLogFile != INVALID_HANDLE_VALUE) {
CloseHandle( g_hLogFile);
g_hLogFile = INVALID_HANDLE_VALUE;
}
}
return fReturn;
}
void ShowUsage()
{
TCHAR szUsage[3000] = "";
strcat (szUsage,
"\nUsage: Client[options] \n"
" \n"
" Options: -s Server Name \n"
" -t Test Type \n"
" -k Keep Connection Alive \n"
" -p Virtual Path \n"
" -b Number of Bytes \n"
" -h Thread Numbers \n"
" -c Loop per Thread \n"
" -e Eatup Memory on Purpose \n"
" \n"
" Test Types: \n"
" \n"
" RC - Sync ReadClient \n"
//" WC - Async WriteClient \n"
//" SWC - Sync WriteClient \n"
" ARC - Async ReadClient \n"
//" TF - TransmitFile \n
" SSF - ServerSupportFunction \n"
" \n"
" Examples: -s stan1_s -t ARC -p \\scripts\\UReadCli.dll -b 1000 -h 2 -c 1 \n"
" -s stan1_s -t RC -p \\INP\\UReadCli.dll -b 1000 -h 10 -c 100 -E 1 \n"
" -s stan1_s -t SSF -p \\INP\\W3test.dll -h 10 -c 100 -k 1 \n"
" \n");
printf (szUsage);
return;
}