📄 cping.cpp
字号:
return E_FAIL;
}
///////////////////////////////////////////////////////// CNetPingFactory.
//
LONG CNetPingFactory::s_nObjects = 0;
LONG CNetPingFactory::s_nLocks = 0;
HANDLE CNetPingFactory::s_hevtDone = NULL;
CNetPingFactory::CNetPingFactory()
{
m_cRef = 1;
}
CNetPingFactory::~CNetPingFactory()
{
m_cRef = 0;
}
ULONG CNetPingFactory::AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
ULONG CNetPingFactory::Release(void)
{
if (InterlockedDecrement(&m_cRef) == 0) {
delete this;
return 0;
}
return 1;
}
HRESULT CNetPingFactory::InitSystem(VOID)
{
s_nObjects = 0;
s_nLocks = 0;
s_hevtDone = CreateEvent(NULL, FALSE, FALSE, NULL);
if (s_hevtDone == NULL) {
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
CheckResult(hr, "Server: CreateEvent");
exit(hr);
}
return S_OK;
}
HRESULT CNetPingFactory::FiniSystem(VOID)
{
if (s_hevtDone != NULL) {
CloseHandle(s_hevtDone);
s_hevtDone = NULL;
}
return S_OK;
}
HRESULT CNetPingFactory::InitObject(VOID)
{
InterlockedIncrement(&s_nObjects);
return S_OK;
}
HRESULT CNetPingFactory::FiniObject(VOID)
{
if (InterlockedDecrement(&s_nObjects) == 0 && s_nLocks == 0)
SetEvent(s_hevtDone);
return S_OK;
}
HRESULT CNetPingFactory::Lock(BOOL fLock)
{
if (fLock) {
InterlockedIncrement(&s_nLocks);
}
else {
if (InterlockedDecrement(&s_nLocks) == 0 && s_nObjects == 0)
SetEvent(s_hevtDone);
}
return S_OK;
}
HRESULT CNetPingFactory::Wait(VOID)
{
DWORD dwWaitResult;
MSG msg;
for (;;) {
dwWaitResult = MsgWaitForMultipleObjects(1, &s_hevtDone,
FALSE, INFINITE,
QS_ALLINPUT);
if (dwWaitResult == WAIT_OBJECT_0) {
ResetEvent(s_hevtDone);
return S_OK;
}
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return E_FAIL;
}
STDMETHODIMP CNetPingFactory::QueryInterface(REFIID riid, void** ppv)
{
if (ppv == NULL)
return E_INVALIDARG;
if (riid == IID_IClassFactory || riid == IID_IUnknown) {
*ppv = (IClassFactory *) this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
HRESULT CNetPingFactory::LockServer (BOOL fLock)
{
return Lock(fLock);
}
STDMETHODIMP CNetPingFactory::CreateInstance(LPUNKNOWN punkOuter,
REFIID riid, void** ppv)
{
LPUNKNOWN punk;
HRESULT hr;
*ppv = NULL;
if (punkOuter != NULL)
return CLASS_E_NOAGGREGATION;
printf(" Server: IClassFactory:CreateInstance\n");
punk = new CNetPingObject;
if (punk == NULL)
return E_OUTOFMEMORY;
hr = punk->QueryInterface(riid, ppv);
punk->Release();
return hr;
}
/////////////////////////////////////////////////////////////// CNetPingObject.
//
CNetPingObject::CNetPingObject()
{
m_cRef = 1;
m_cbLast = ~0u;
m_cbOut = 2;
CNetPingFactory::InitObject();
}
CNetPingObject::~CNetPingObject()
{
CNetPingFactory::FiniObject();
}
STDMETHODIMP CNetPingObject::QueryInterface(REFIID riid, void** ppv)
{
if (ppv == NULL)
return E_INVALIDARG;
if (riid == IID_IUnknown || riid == IID_IPing) {
*ppv = (IPing *) this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CNetPingObject::AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) CNetPingObject::Release(void)
{
if (InterlockedDecrement(&m_cRef) == 0) {
delete this;
return 0;
}
return 1;
}
STDMETHODIMP CNetPingObject::Ping()
{
return S_OK;
}
STDMETHODIMP CNetPingObject::PingToServer(LPSTR pszString)
{
return S_OK;
}
STDMETHODIMP CNetPingObject::PingToClient(LPSTR *ppszString)
{
LPSTR pszString = (LPSTR)CoTaskMemAlloc(m_cbOut);
if (pszString == NULL)
return E_OUTOFMEMORY;
CopyMemory(pszString, g_pBuffer, m_cbOut);
*ppszString = pszString;
return S_OK;
}
STDMETHODIMP CNetPingObject::PingToClientSize(ULONG cbOut)
{
if (cbOut < 1) {
return E_INVALIDARG;
}
InitializeString((LPSTR)g_pBuffer, cbOut);
m_cbOut = cbOut;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////
//
class CSampleRecord
{
public:
DOUBLE m_dTime;
FILETIME m_nWhen;
LONG m_cbToClient;
LONG m_cbToServer;
DOUBLE m_dDcom;
DOUBLE m_dRpc;
DOUBLE m_dUdp;
DOUBLE m_dNet;
protected:
static LONG s_cbToClient;
static LONG s_cbToServer;
public:
CSampleRecord();
CSampleRecord(IPing *pIPing, LONG cbToClient, LONG cbToServer);
HRESULT Measure(IPing *pIPing, LONG cbToClient, LONG cbToServer);
HRESULT Write(FILE *fp);
double GetTime() { return m_dTime; }
FILETIME GetWhen() { return m_nWhen; }
LONG GetToClient() { return m_cbToClient; }
LONG GetToServer() { return m_cbToServer; }
};
//////////////////////////////////////////////////////////////////////////////
//
LONG CSampleRecord::s_cbToClient = 0;
LONG CSampleRecord::s_cbToServer = 0;
//////////////////////////////////////////////////////////////////////////////
//
CSampleRecord::CSampleRecord()
{
m_dTime = 0;
m_dDcom = 0;
m_dRpc = 0;
m_dUdp = 0;
m_dNet = 0;
}
CSampleRecord::CSampleRecord(IPing *pIPing, LONG cbToClient, LONG cbToServer)
{
Measure(pIPing, cbToClient, cbToServer);
}
HRESULT CSampleRecord::Measure(IPing *pIPing, LONG cbToClient, LONG cbToServer)
{
HRESULT hr;
LONGLONG llBeg;
LONGLONG llEnd;
GetSystemTimeAsFileTime(&m_nWhen);
m_cbToClient = cbToClient;
m_cbToServer = cbToServer;
if (cbToClient == 0 && cbToServer == 0) {
PingLoadCycleCount(llBeg);
hr = Detour_IPing_Ping(pIPing);
PingLoadCycleCount(llEnd);
}
else if (cbToClient) {
if (s_cbToClient != cbToClient) {
hr = pIPing->PingToClientSize(cbToClient);
s_cbToClient = cbToClient;
}
LPSTR pszString = NULL;
PingLoadCycleCount(llBeg);
hr = Detour_IPing_PingToClient(pIPing, &pszString);
PingLoadCycleCount(llEnd);
LONG cb = strlen(pszString) + 1;
ASSERT(cb == cbToClient);
if (pszString) {
CoTaskMemFree(pszString);
pszString = NULL;
}
}
else {
if (s_cbToServer != cbToServer) {
InitializeString((LPSTR)g_pBuffer, cbToServer);
s_cbToServer = cbToServer;
}
PingLoadCycleCount(llBeg);
hr = Detour_IPing_PingToServer(pIPing, (LPSTR)g_pBuffer);
PingLoadCycleCount(llEnd);
}
if (FAILED(hr)) {
fprintf(g_fpLog, ";; Operation failed: %08lx\n", hr);
fflush(g_fpLog);
exit(999);
m_dTime = -1.0;
return hr;
}
if (g_fSummarize) {
SummarizeCycles();
m_dDcom = (double)s_rgCycles[E_DCOM] * g_dMsPerCycle;
m_dRpc = (double)s_rgCycles[E_RPC] * g_dMsPerCycle;
m_dUdp = (double)s_rgCycles[E_UDP] * g_dMsPerCycle;
m_dNet = (double)s_rgCycles[E_NET] * g_dMsPerCycle;
}
m_dTime = (double)(llEnd - llBeg) * g_dMsPerCycle;
return S_OK;
}
HRESULT CSampleRecord::Write(FILE *fp)
{
SYSTEMTIME st;
FILETIME ft;
FileTimeToLocalFileTime(&m_nWhen, &ft);
FileTimeToSystemTime(&ft, &st);
fprintf(fp, "%02d/%02d %2d:%02d:%02d %6d %d %6.3f [ %6.3f %6.3f %6.3f %6.3f ]\n",
st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
m_cbToClient, m_cbToServer, m_dTime,
m_dDcom, m_dRpc, m_dUdp, m_dNet);
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////
//
double NetTest(HKEY hNetwork, IPing *pIPing,
BOOLEAN fToClient, LONG cbPacket, LONG nCount)
{
//////////////////////////////////////////////////////////////////// ToClient.
//
double msAvg = 0.0;
double msMin = 1.0e12;
double msMax = 0.0;
ULONG nMax = 999;
ULONG nMin = 999;
if (fToClient)
printf(">Client %6d %6d ", cbPacket, nCount);
else
printf(">Server %6d %6d ", cbPacket, nCount);
for (LONG n = 0; n < nCount; n++) {
double ms;
if (fToClient) {
ms = CSampleRecord(pIPing, cbPacket, 0).GetTime();
}
else {
ms = CSampleRecord(pIPing, 0, cbPacket).GetTime();
}
if (ms < 0)
break;
if (msMin > ms) {
msMin = ms;
nMin = n;
}
if (msMax < ms) {
msMax = ms;
nMax = n;
}
msAvg += ms;
}
if (nCount)
msAvg /= nCount;
if (cbPacket == 0)
g_dLatency = msMin;
double mbps = (double)cbPacket / msMin;
mbps *= 8.0 * 1000.0 / 1024.0 / 1024.0;
double mbps2 = (double)cbPacket / (msMin - g_dLatency);
mbps2 *= 8.0 * 1000.0 / 1024.0 / 1024.0;
if (cbPacket == 0)
mbps2 = 0;
if (hNetwork != NULL) {
WCHAR wzKey[64];
WCHAR wzLatency[64];
if (fToClient)
swprintf(wzKey, L"ToClient\\%d", cbPacket);
else
swprintf(wzKey, L"ToServer\\%d", cbPacket);
swprintf(wzLatency, L"%I64d", msAvg);
RegSetValue(hNetwork, wzKey, REG_SZ, wzLatency, wcssize(wzLatency));
}
printf("%8.3f %8.3f %8.3f %9.4f %8.3f %9.4f%3d\n",
msMin,
msAvg,
msMax,
mbps,
msMin - g_dLatency,
mbps2,
nMax);
return mbps;
}
//////////////////////////////////////////////////////////////////////// main.
static WCHAR wzServers[32][64];
static int nServers = 0;
void Sample_Fixed(IPing *pIPing)
{
CSampleRecord csrRecords[512];
LONG nRecords = 0;
HRESULT hr;
double dAvg = 0;
double dMin = 500000.0;
double dMax = 0.0;
double dMinDcom = dMin;
double dMinRpc = dMin;
double dMinUdp = dMin;
double dMinNet = dMin;
for (int i = 0; i < 512; i++) {
CSampleRecord& csr = csrRecords[nRecords++];
hr = csr.Measure(pIPing, g_nFixedToClient, g_nFixedToServer);
double d = csr.GetTime();
if (dMin > d)
dMin = d;
if (dMax < d)
dMax = d;
if (dMinDcom > csr.m_dDcom)
dMinDcom = csr.m_dDcom;
if (dMinRpc > csr.m_dRpc)
dMinRpc = csr.m_dRpc;
if (dMinUdp > csr.m_dUdp)
dMinUdp = csr.m_dUdp;
if (dMinNet > csr.m_dNet)
dMinNet = csr.m_dNet;
dAvg += d;
}
dAvg /= 512;
printf("size: %d, min: %.3f, max: %.3f avg: %.3f [ %8.3f %8.3f %8.3f %8.3f ]\n",
g_nFixedToClient, dMin, dMax, dAvg, dMinDcom, dMinRpc, dMinUdp, dMinNet);
for (int n = 0; n < nRecords; n++)
csrRecords[n].Write(g_fpLog);
}
void Sample_Simple(IPing *pIPing)
{
CSampleRecord csrRecords[512];
LONG nRecords = 0;
HRESULT hr;
for (int cb = 0; cb < 64000; cb = cb ? cb << 1 : 32) {
double n[5];
for (int i = 0; i < 5; i++) {
CSampleRecord& csr = csrRecords[nRecords++];
hr = csr.Measure(pIPing, cb, 0);
n[i] = csr.GetTime();
}
double nAvg = 0;
double nApx = 0;
double nMin = n[0];
double nMax = n[0];
for (i = 0; i < 5; i++) {
if (nMin > n[i])
nMin = n[i];
if (nMax < n[i])
nMax = n[i];
nAvg += n[i];
}
nApx = nAvg - nMax;
nAvg /= 5;
nApx /= 4;
printf("min: %8.3f ms (%6d) %7.3f%7.3f%7.3f%7.3f%7.3f:%8.3f%8.3f\n",
nMin, cb, n[0], n[1], n[2], n[3], n[4], nAvg, nApx);
#ifdef INCLUDE_THIS
if (nMin > 300)
break;
#endif
}
for (int n = 0; n < nRecords; n++)
csrRecords[n].Write(g_fpLog);
}
void Sample_More(IPing *pIPing)
{
CSampleRecord csrRecords[64];
LONG nRecords = 0;
for (int cb = 0; cb < 64000; cb = cb ? cb << 1 : 32) {
for (int i = 0; i < 64; 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 < 64; 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",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -