📄 cping.cpp
字号:
nMin, cb, nMax, nAvg);
for (int n = 0; n < nRecords; n++)
csrRecords[n].Write(g_fpLog);
nRecords = 0;
}
}
void Sample_Less(IPing *pIPing)
{
CSampleRecord csrRecords[16];
LONG nRecords = 0;
for (int cb = 0; cb < 64000; cb = cb ? cb << 1 : 16) {
for (int i = 0; i < 16; i++) {
CSampleRecord& csr = csrRecords[nRecords++];
csr.Measure(pIPing, cb, 0);
}
double nAvg = 0;
double nMin = csrRecords[0].GetTime();
double nMax = csrRecords[0].GetTime();
for (i = 0; i < 16; i++) {
double n = csrRecords[i].GetTime();
if (nMin > n)
nMin = n;
if (nMax < n)
nMax = n;
nAvg += n;
}
nAvg /= i;
printf("min: %8.3f ms (%6d) : %8.3f %8.3f\n",
nMin, cb, nMax, nAvg);
for (int n = 0; n < nRecords; n++)
csrRecords[n].Write(g_fpLog);
nRecords = 0;
}
}
void Sample_Profile(IPing *pIPing)
{
CSampleRecord csrRecords[64];
double dbZero = 0;
printf("\nPacket_Size_ Min_Latency Max_Latency Avg_Latency "
"Relative_Bnd ___Bandwidth\n");
for (int cb = 0; cb < 256 * 1024;) {
for (int n = 0; n < 64; n++) {
CSampleRecord& csr = csrRecords[n];
csr.Measure(pIPing, cb, 0);
}
double dbAvg = 0;
double dbMin = csrRecords[0].GetTime();
double dbMax = csrRecords[0].GetTime();
LONG nMin = 0;
LONG nMax = 0;
for (n = 0; n < 64; n++) {
double db = csrRecords[n].GetTime();
if (dbMin > db) {
dbMin = db;
nMin = n;
}
if (dbMax < db) {
dbMax = db;
nMax = n;
}
dbAvg += db;
}
dbAvg /= n;
if (cb == 0) {
dbZero = dbMin;
}
double dbBnd = 0;
if (dbMin > dbZero) {
dbBnd = ((8 * cb) * 1000.0) / (1024 * 1024);
dbBnd /= dbMin - dbZero;
}
double dbReal = ((8 * cb) * 1000.0) / (1024 * 1024) / dbMin;
printf("%6d bytes %9.3fms %9.3fms %9.3fms %8.3fMbps %8.3fMbps\r",
cb, dbMin, dbMax, dbAvg, dbBnd, dbReal);
csrRecords[nMin].Write(g_fpLog);
if (cb < 2048) {
cb++;
}
else if (cb < 4096) {
cb += 2;
}
else if (cb < 8192)
cb += 8;
else if (cb < 16384)
cb += 32;
else
cb += 128;
}
}
//////////////////////////////////////////////////////////////////////////////
//
class CInit
{
public:
CInit(HINSTANCE hinst)
{
m_hinst = hinst;
AllocConsole();
// initialize COM for free-threading
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) {
CheckResult(hr, "CoInitializeEx");
exit(hr);
}
ULONG ul = iping_DllMain(m_hinst, DLL_PROCESS_ATTACH, NULL);
ASSERT(ul);
}
~CInit()
{
ULONG ul = iping_DllMain(m_hinst, DLL_PROCESS_DETACH, NULL);
ASSERT(ul);
CoUninitialize();
}
private:
HINSTANCE m_hinst;
};
class CInitStub
{
public:
CInitStub()
{
m_dwRegister = ~0u;
IClassFactory *pClassFactory = NULL;
HRESULT hr = iping_DllGetClassObject(IID_IPing,
IID_IUnknown,
(void **)&pClassFactory);
if (FAILED(hr)) {
CheckResult(hr, "IPing_DllGetClassObject");
ASSERT(SUCCEEDED(hr));
}
if (pClassFactory) {
hr = CoRegisterClassObject(IID_IPing,
pClassFactory,
CLSCTX_SERVER,
REGCLS_MULTIPLEUSE,
&m_dwRegister);
if (FAILED(hr)) {
ASSERT(SUCCEEDED(hr));
CheckResult(hr, "CoRegisterClassObject(IID_IPing)\n");
}
pClassFactory->Release();
pClassFactory = NULL;
}
}
~CInitStub()
{
if (m_dwRegister != ~0u) {
CoRevokeClassObject(m_dwRegister);
m_dwRegister = ~0u;
}
}
private:
DWORD m_dwRegister;
};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
{
CInit cinit(hinst);
int argc;
WCHAR **argv = CommandLineToArgvW(GetCommandLineW(), &argc);
HRESULT hr;
BOOLEAN fUnreg = FALSE;
BOOLEAN fNeedHelp = FALSE;
BOOLEAN fServer = FALSE;
BOOLEAN fLong = FALSE;
BOOLEAN fProfile = FALSE;
BOOLEAN fInstrument = TRUE;
BOOLEAN fFixed = FALSE;
s_nThread = GetCurrentThreadId();
printf("Ping Network Server: [" __DATE__ " " __TIME__ "]\n");
for (int arg = 1; arg < argc; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
WCHAR *argn = argv[arg] + 1;
WCHAR *argp = argn;
while (*argp && *argp != ':')
argp++;
if (*argp == ':')
*argp++ = '\0';
switch (argn[0]) {
case 'f': // Fixed
case 'F':
fFixed = TRUE;
g_nFixedToClient = _wtoi(argp);
g_nFixedToServer = 0;
break;
case 'i':
case 'I': // Instrument
fInstrument = !fInstrument;
break;
case 'n': // Null
case 'N':
fFixed = TRUE;
g_nFixedToClient = g_nFixedToServer = 0;
break;
case 'l': // Long-term loop
case 'L':
fLong = !fLong;
break;
case 'p': // Profile Network
case 'P':
fProfile = !fProfile;
break;
case 's': // Server
case 'S':
fServer = !fServer;
break;
case 'u': // Unregister
case 'U':
fUnreg = !fUnreg;
break;
case 'x': // Xtract Data
case 'X':
g_fSummarize = !g_fSummarize;
break;
case '?': // Help
fNeedHelp = TRUE;
break;
case '\0': // Local Host
wcscpy(wzServers[nServers++], L"localhost");
ASSERT(nServers <= 32);
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %ls\n", argv[arg]);
break;
}
}
else {
wcscpy(wzServers[nServers++], argv[arg]);
ASSERT(nServers <= 32);
}
}
if (argc == 1 || (nServers == 0 && !fUnreg && !fServer))
fNeedHelp = TRUE;
if (fNeedHelp) {
printf("Usage:\n"
" cping [options] [hosts] ..or.. cping [options] /s\n"
"Options:\n"
" /u : Unregister.\n"
" /s : Act as a server, waiting for clients.\n"
" /? : Display this help screen.\n"
"Client Options:\n"
" /l : Long-term loop test. (Default: %3s)\n"
" /p : Profile test. (Default: %3s)\n"
" /n : Null (0 length) test. (Default: Off)\n"
" /f:size : Fixed sized packets. (Default: %3s)\n"
" /x : Xtract detailed DCOM/RPC/NET data. (Default: %3s)\n"
" /i : Toggle instrumentation. (Default: %3s)\n",
fLong ? "On" : "Off",
fProfile ? "On" : "Off",
fFixed ? "On" : "Off",
g_fSummarize ? "Off" : "Off",
fInstrument ? "On" : "Off");
exit(1);
}
//////////////////////////////////////////////////////////////////////////
if (fUnreg) {
Unregister();
}
else {
//////////////////////////////////////////////////////////////////////////////
//
CInitStub cinitstub;
// Register in the registry.
Register();
if (fInstrument) {
RerouteEntryPoints();
}
LONGLONG llCycles;
hr = GetClockInfo(&llCycles);
ASSERT(SUCCEEDED(hr));
g_dCyclesPerSecond = (double)llCycles;
g_dMsPerCycle = (double)1000.0 / (double)llCycles;
g_pBuffer = CoTaskMemAlloc(g_cbBufferMax);
ASSERT(g_pBuffer);
if (fServer) {
// register the class-object with OLE
CNetPingFactory::InitSystem();
CNetPingFactory *pClassFactory = new CNetPingFactory;
printf("Registering.\n");
DWORD dwRegister;
hr = CoRegisterClassObject(CLSID_NetPingObject, pClassFactory,
CLSCTX_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
printf("Releasing Registered.\n");
pClassFactory->Release();
if (FAILED(hr)) {
CheckResult(hr, "Server: CoRegisterClassObject");
ASSERT(SUCCEEDED(hr));
}
printf(" Server: Waiting <<<Press Ctrl-C to stop.>>>\n");
for (;;) {
CNetPingFactory::Wait();
}
hr = CoRevokeClassObject(dwRegister);
if (FAILED(hr)) {
CheckResult(hr, "Server: CoRevokeClassObject");
ASSERT(SUCCEEDED(hr));
}
CNetPingFactory::FiniSystem();
}
else if (nServers) {
LONGLONG llBeg;
LONGLONG llEnd;
COSERVERINFO csi;
MULTI_QI mq;
ULONG cb = 4096;
ULONG cbDone = 0;
//////////////////////////////////////////////////////////////////
//
g_fpLog = fopen("cping.dat", "a+");
printf("Processor Speed: %.0f MHz\n", g_dCyclesPerSecond / 1000000.0);
DWORD dwSize = arrayof(g_wzClientName);
GetComputerName(g_wzClientName, &dwSize);
if (g_fpLog) {
fprintf(g_fpLog, ";;; %ls - %.0f MHz\n",
g_wzClientName,
g_dCyclesPerSecond / 1000000.0);
}
for (int n = 0; n < nServers; n++) {
if (g_wzServerName[0] == '\\' && g_wzServerName[1] == '\\') {
wcscpy(g_wzServerName, wzServers[n] + 2);
}
else
wcscpy(g_wzServerName, wzServers[n]);
printf("Server: %ls->%ls\n", g_wzClientName, g_wzServerName);
if (g_fpLog) {
fprintf(g_fpLog, ";; %ls %ls\n", g_wzClientName, g_wzServerName);
}
ZeroMemory(&csi, sizeof(csi));
csi.pwszName = wzServers[n];
// create a remote instance of the object on the argv[1] machine
mq.pIID = &IID_IPing;
mq.pItf = NULL;
mq.hr = S_OK;
PingLoadCycleCount(llBeg);
hr = CoCreateInstanceEx(CLSID_NetPingObject, NULL, CLSCTX_SERVER,
&csi, 1, &mq);
PingLoadCycleCount(llEnd);
printf(" CoCreateInstanceEx: %0.4f seconds (%lu ticks)\n",
(double)(llEnd - llBeg)/(double)llCycles,
(ULONG)(llEnd - llBeg));
CheckResult(mq.hr, "CoCreateInstanceEx [mq]");
CheckResult(hr, "CoCreateInstanceEx");
if (FAILED(hr)) {
CheckResult(hr, "CoCreateInstanceEx");
continue;
}
//////////////////////////////////////////////////////////////////
//
IPing *pIPing = (IPing *)mq.pItf;
LPSTR pszString = NULL;
hr = pIPing->Ping();
if (FAILED(hr)) {
CheckResult(hr, "Ping");
}
ASSERT(SUCCEEDED(hr));
hr = Detour_IPing_Ping(pIPing);
if (FAILED(hr)) {
CheckResult(hr, "Ping");
}
ASSERT(SUCCEEDED(hr));
ZeroCycles();
if (fFixed) {
Sample_Fixed(pIPing);
}
else if (fProfile) {
Sample_Profile(pIPing);
}
else {
Sample_Simple(pIPing);
if (fLong) {
for (;;) {
Sample_More(pIPing);
for (int j = 0; j < 5; j++) {
Sleep(20000);
Sample_Simple(pIPing);
}
Sleep(20000);
for (int i = 0; i < 18; i++) {
Sample_Less(pIPing);
for (int j = 0; j < 3; j++) {
Sleep(20000);
Sample_Simple(pIPing);
}
Sleep(20000);
}
}
}
}
pIPing->Release();
}
if (g_fpLog) {
fclose(g_fpLog);
g_fpLog = NULL;
}
}
if (g_pBuffer) {
CoTaskMemFree(g_pBuffer);
g_pBuffer = NULL;
}
Sleep(2);
if (fInstrument && !g_fSummarize && s_rgCounts[E_Proxy]) {
printf("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
"::::::::::::::::::\n");
printf(":: Instrumented Cycles: _____Function Time__ "
"________Total Time__ : Count\n");
for (LONG n = E_DCOM; n < E_MaxValue; n++) {
s_rgCycles[n] = 0;
s_rgTotals[n] = 0;
s_rgCounts[n] = 0;
}
for (n = E_MinValue + 1; n < E_MaxValue; n++) {
DumpCycles(n);
}
printf("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
"::::::::::::::::::\n");
printf(":: Protocol Cycles:\n");
for (n = E_DcomBeg; n <= E_DcomEnd; n++) {
s_rgCycles[E_DCOM] += s_rgCycles[n];
s_rgTotals[E_DCOM] += s_rgTotals[n];
s_rgCounts[E_DCOM] += s_rgCounts[n];
}
for (n = E_RpcBeg; n <= E_RpcEnd; n++) {
s_rgCycles[E_RPC] += s_rgCycles[n];
s_rgTotals[E_RPC] += s_rgTotals[n];
s_rgCounts[E_RPC] += s_rgCounts[n];
}
for (n = E_UdpBeg; n <= E_UdpEnd; n++) {
s_rgCycles[E_UDP] += s_rgCycles[n];
s_rgTotals[E_UDP] += s_rgTotals[n];
s_rgCounts[E_UDP] += s_rgCounts[n];
}
for (n = E_NetBeg; n <= E_NetEnd; n++) {
s_rgTotals[E_NET] += s_rgCycles[n];
s_rgCycles[E_NET] += s_rgTotals[n];
s_rgCounts[E_NET] += s_rgCounts[n];
}
DumpCycles(E_DCOM);
DumpCycles(E_RPC);
DumpCycles(E_UDP);
DumpCycles(E_NET);
printf("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
"::::::::::::::::::\n");
printf(":: Protocol Cycles Per DCOM Call:\n");
s_rgCycles[E_DCOM] /= s_rgCounts[E_DCOM];
s_rgCycles[E_RPC] /= s_rgCounts[E_DCOM];
s_rgCycles[E_UDP] /= s_rgCounts[E_DCOM];
s_rgCycles[E_NET] /= s_rgCounts[E_DCOM];
s_rgTotals[E_DCOM] /= s_rgCounts[E_DCOM];
s_rgTotals[E_RPC] /= s_rgCounts[E_DCOM];
s_rgTotals[E_UDP] /= s_rgCounts[E_DCOM];
s_rgTotals[E_NET] /= s_rgCounts[E_DCOM];
DumpCycles(E_DCOM);
DumpCycles(E_RPC);
DumpCycles(E_UDP);
DumpCycles(E_NET);
}
}
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -