DlgStatistics.cpp
上传用户:gnaf34
上传日期:2022-04-22
资源大小:1657k
文件大小:25k
- /*
- * DlgStatistics.cxx
- *
- * Implementation file
- *
- * Copyright (c) ITEC-Ohio, 2002.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Open H323 Library available at http://www.openh323.org
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- */
- #include "stdafx.h"
- #include <iostream.h>
- #include <fstream.h>
- #include <ptlib.h>
- #include <string.h>
- //#include <winsock.h>
- #include "main.h"
- #include "ping.h"
- #include "BeaconClient.h"
- #include "DlgStatistics.h"
- #include <time.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDlgStatistics dialog
- extern BeaconClient* globalInstance;
- extern const char* globalEndReason;
- extern int FlagEndPoint;
- extern char CurrentDrive_tmp1[MAX_PATH];
- extern char tmpCurrDrvStr[MAX_PATH];
- extern CString consoleStr;
- //For Statistics Part
- extern int StartTimeGlobalYear;
- extern int StartTimeGlobalMonth;
- extern int StartTimeGlobalDay;
- extern int StartTimeGlobalHour;
- extern int StartTimeGlobalMinute;
- extern int StartTimeGlobalSecond;
- extern DWORD RoundTripTimeDelayGlobal;
- extern PStringStream DurationTimeGlobal;
- extern DWORD AudioFrameRateGlobal;
- extern DWORD PacketSentGlobal;
- extern DWORD OctetSendGlobal;
- extern DWORD MaximumSendTimeGlobal;
- extern DWORD AverageSendTimeGlobal;
- extern DWORD MinimumSendTimeGlobal;
- extern DWORD PacketsReceivedGlobal;
- extern DWORD OctetsReceivedGlobal;
- extern DWORD MaximumReceiveTimeGlobal;
- extern DWORD AverageReceiveTimeGlobal;
- extern DWORD MinimumReceiveTimeGlobal;
- extern DWORD PacketsLostGlobal;
- extern DWORD PacketsOutOfOrderGlobal;
- extern DWORD PacketsOutTooLateGlobal;
- extern DWORD JitterTimeGlobal;
- extern PString PayloadTypeGlobal;
- extern PString ReceivedDTMFMessages;
- PString TmpReceivedDTMFMessages;
- UINT StatisticTimer;
- extern UINT ConnectionTimer;
- extern int is_MsgBox_Display; // 0 means globalendReason has NOT been displayed,
- extern bool bCalling;
- extern CString ipglobal;
- int prevpingresult = 0;
- int pingresult;
- hostent *host1 = NULL;
- char hostname[80];
- CString localmachine;
- int PacketSentStat = 0;
- int DurationHour;
- int DurationMinute;
- int DurationSecond;
- CString sessionStartTime;
- CString sessionEndTime;
- CString sessionDate;
- //Ping Report Variables
- CString avgPingLatency;
- CString medianPingLatency;
- CString sdPingLatency;
- CString minPingLatency;
- CString maxPingLatency;
- CString P50PingLatency;
- CString P90PingLatency;
- //Codec Latency Report Variables
- CString avgCodecLatency;
- CString medianCodecLatency;
- CString sdCodecLatency;
- CString minCodecLatency;
- CString maxCodecLatency;
- CString P50CodecLatency;
- CString P90CodecLatency;
- //Jitter Report Variables
- CString avgJitterLatency;
- CString medianJitterLatency;
- CString sdJitterLatency;
- CString minJitterLatency;
- CString maxJitterLatency;
- CString P50JitterLatency;
- CString P90JitterLatency;
- //PacketLoss Report Variables
- CString avgPacketLossLatency;
- CString medianPacketLossLatency;
- CString sdPacketLossLatency;
- CString minPacketLossLatency;
- CString maxPacketLossLatency;
- CString P50PacketLossLatency;
- CString P90PacketLossLatency;
- extern CString ReportStr;
- //Initialize GNUPlot markers to define good/acceptable/unacceptable for statistics
- // Packet Lost
- const char *pktlost_good = "0.0";
- const char *pktlost_acceptable = "0.5";
- const char *pktlost_unacceptable = "1.5";
- // Round Trip Time / Latency
- const char *rtd_good = "0";
- const char *rtd_acceptable = "200";
- const char *rtd_unacceptable = "400";
- // Audio Jitter
- //This information is got from ITU G.114 as stated in
- //Wainhouse Research Whitepaper available at-
- //http://www.wainhouse.com/files/papers/wr-qos-in-ip-networks.pdf
- //Defaults for Audio Jitter:
- //audjitter_good = "0";
- //audjitter_acceptable = "20";
- //audjitter_unacceptable = "50";
- const char *audjitter_good = "0";
- const char *audjitter_acceptable = "20";
- const char *audjitter_unacceptable = "50";
- CDlgStatistics::CDlgStatistics(CWnd* pParent /*=NULL*/)
- : CDialog(CDlgStatistics::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CDlgStatistics)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT}
- gethostname(hostname, sizeof(hostname));
- host1 = gethostbyname(hostname);
- localmachine = inet_ntoa(*(reinterpret_cast<in_addr*>(host1->h_addr)));
- }
- void CDlgStatistics::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CDlgStatistics)
- // NOTE: the ClassWizard will add DDX and DDV calls here
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CDlgStatistics, CDialog)
- //{{AFX_MSG_MAP(CDlgStatistics)
- ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)
- ON_WM_PAINT()
- ON_WM_TIMER()
- ON_WM_CREATE()
- ON_WM_CANCELMODE()
- ON_WM_CAPTURECHANGED()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDlgStatistics message handlers
- //BeaconClient *instance;
- void CDlgStatistics::OnButtonStart()
- {
- }
- void CDlgStatistics::OnPaint()
- {
- TRY {
- CPaintDC dc(this); // device context for painting
- // For statistic part, we are using WM_TIMER to collect
- // statistic for every second by command SetTimer(1,1000,0)
- // where 1000 = 1000 mile second
-
- CDlgStatistics::KillTimer(StatisticTimer);
-
- if (globalInstance != NULL){
- if (globalInstance->endpoint != NULL){
- StatisticTimer = CDlgStatistics::SetTimer(20,1000,0);
- }
- else{
- CDlgStatistics::KillTimer(StatisticTimer);
- }
- }
- // Do not call CDialog::OnPaint() for painting messages
- } // End TRY
- CATCH_ALL(e){
- // Put some delay here
- }
- END_CATCH_ALL
-
- }
- void CDlgStatistics::OnTimer(UINT nIDEvent)
- {
- // TODO: Add your message handler code here and/or call default
- // Collect statistic for every second (Using WM_TIMER)
- // Display it to window
- char buffer[200];
- CString strtext;
- CString strhour;
- CString strminute;
- CString strsecond;
- CString StartTime;
- CString CurrentTimeStat;
- CString PayloadTypeName;
- CString strCurrentYear;
- CString strCurrentMonth;
- CString strCurrentDay;
- CString strCurrentHour;
- CString strCurrentMinute;
- CString strCurrentSecond;
-
- int CurrentHour;
- int CurrentMinute;
- int CurrentSecond;
- int CurrentYear;
- int CurrentMonth;
- int CurrentDay;
- CString strCurrentMonth_tmp;
- CString tmpStrVar;
- CString CurrentDateTimeStat;
- CString str;
- int stat;
- TRY {
-
- CTime time = CTime::GetCurrentTime();
- CEdit *p_FrameRate = (CEdit *)GetDlgItem(IDC_EDIT_FrameRate);
- CEdit *p_PacketSent = (CEdit *)GetDlgItem(IDC_EDIT_PACKET_SENT);
- CEdit *p_OctetSend = (CEdit *)GetDlgItem(IDC_EDIT_OCTET_SENT);
- CEdit *p_MaxSendTime = (CEdit *)GetDlgItem(IDC_EDIT_MAXIMUM_SENDTIME);
- CEdit *p_AvSendTime = (CEdit *)GetDlgItem(IDC_EDIT_AVERAGE_SENDTIME);
- CEdit *p_MinSendTime = (CEdit *)GetDlgItem(IDC_EDIT_MINIMUM_SENDTIME);
- CEdit *p_PacketReceived = (CEdit *)GetDlgItem(IDC_EDIT_PACKET_RECEIVED);
- CEdit *p_OctetReceived = (CEdit *)GetDlgItem(IDC_EDIT_OCTET_RECEIVED);
- CEdit *p_MaxRecTime = (CEdit *)GetDlgItem(IDC_EDIT_MAXIMUM_RECEIVETIME);
- CEdit *p_AvRecTime = (CEdit *)GetDlgItem(IDC_EDIT_AVERAGE_RECEIVETIME);
- CEdit *p_MinRecTime = (CEdit *)GetDlgItem(IDC_MINIMUM_RECEIVETIME);
- CEdit *p_PacketLoss = (CEdit *)GetDlgItem(IDC_EDIT_PL);
- CEdit *p_PacketOutOfOrder = (CEdit *)GetDlgItem(IDC_Packet_Out_Of_Order2);
- CEdit *p_PacketTooLate = (CEdit *)GetDlgItem(IDC_Packet_Too_Late2);
- CEdit *p_AudioJitter = (CEdit *)GetDlgItem(IDC_EDIT_AJ);
- CEdit *p_StartTime = (CEdit *)GetDlgItem(IDC_StartTime1);
- CEdit *p_RoundTripDelay = (CEdit *)GetDlgItem(IDC_RoundTripTime);
- // Server IP
- CEdit *p_ServerIP = (CEdit *)GetDlgItem(IDC_SERVER_IP);
- //Client IP
- CEdit *p_ClientIP = (CEdit *)GetDlgItem(IDC_CLIENT_IP);
- CEdit *p_PayloadType = (CEdit *)GetDlgItem(IDC_PayloadType);
- // Open All necessary files to capture all statistic in real time
- // Fields to be captured:
- // Date and Time Stamp
- // Frame Rate
- // Packet Sent
- // Octet Sent
- // Maximum Send Time
- // Average Send Time
- // Minimum Send Time
- // Packet Received
- // Octet Received
- // Maximum Receive Time
- // Average Receive Time
- // Minimum Receive Time
- // Packet Loss
- // Packet Out Of Order
- // Packet Too Late
- // Audio Jitter
-
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"timestamp.txt");
- fstream fs1( tmpCurrDrvStr, ios::out | ios::app ); // Date and Time Stamp
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"ploadtype.txt");
- fstream fs2( tmpCurrDrvStr, ios::out | ios::app ); // Payload Type
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"pktloss.txt");
- fstream fs3( tmpCurrDrvStr, ios::out | ios::app ); // Packet Loss
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"audjitter.txt");
- fstream fs4( tmpCurrDrvStr, ios::out | ios::app ); // Audio Jitter
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"rtd.txt");
- fstream fs5( tmpCurrDrvStr, ios::out | ios::app ); // Round Trip Delay
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"pktsent.txt");
- fstream fs6( tmpCurrDrvStr, ios::out | ios::app ); // Packet Sent
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"octsent.txt");
- fstream fs7( tmpCurrDrvStr, ios::out | ios::app ); // Octet Sent
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"pktrecvd.txt");
- fstream fs8( tmpCurrDrvStr, ios::out | ios::app ); // Packet Received
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"octrecvd.txt");
- fstream fs9( tmpCurrDrvStr, ios::out | ios::app ); // Octet Received
- //GNUPlot related files
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"pktloss_gplot.txt");
- fstream fs3gplot( tmpCurrDrvStr, ios::out | ios::app ); // Packet Loss_gnuplot
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"audjitter_gplot.txt");
- fstream fs4gplot( tmpCurrDrvStr, ios::out | ios::app ); // Audio Jitter_gnuplot
- sprintf(tmpCurrDrvStr,"%s\\%s",CurrentDrive_tmp1,"rtd_gplot.txt");
- fstream fs5gplot( tmpCurrDrvStr, ios::out | ios::app ); // Round Trip Delay_gnuplot
-
- if (globalInstance->endpoint != NULL){
- stat = globalInstance->GetStatistics();
- if (stat == 0){
- SetDlgItemText(IDC_EDIT_CALLSTATUS, "In Session");
-
- CTime start_time = CTime(StartTimeGlobalYear,StartTimeGlobalMonth,StartTimeGlobalDay,StartTimeGlobalHour,StartTimeGlobalMinute,StartTimeGlobalSecond);
- CTimeSpan dur = time - start_time;
- DurationHour = dur.GetTotalHours();
- DurationMinute = dur.GetMinutes();
- DurationSecond = dur.GetSeconds();
- CurrentHour = time.GetHour();
- CurrentMinute = time.GetMinute();
- CurrentSecond = time.GetSecond();
- CurrentYear = time.GetYear();
- CurrentMonth = time.GetMonth();
- CurrentDay = time.GetDay();
- // Implement Time Difference because we want to
- // Map difference between PTime and CTime
- // Get Duration
- strhour = _itoa(DurationHour,buffer,10);
- strminute = _itoa(DurationMinute,buffer,10);
- strsecond = _itoa(DurationSecond,buffer,10);
- strCurrentHour = _itoa(CurrentHour,buffer,10);
- strCurrentMinute = _itoa(CurrentMinute,buffer,10);
- strCurrentSecond = _itoa(CurrentSecond,buffer,10);
- strCurrentYear = _itoa(CurrentYear,buffer,10);
- strCurrentMonth = time.Format("%B"); // _itoa(CurrentMonth,buffer,10);
- strCurrentDay = _itoa(CurrentDay,buffer,10);
-
- strCurrentMonth_tmp = _itoa(CurrentMonth,buffer,10);
- StartTime = strhour + ":" + strminute + ":" + strsecond; // Duration Time
-
- CurrentTimeStat = strCurrentHour + ":" + strCurrentMinute + ":" + strCurrentSecond;
- CurrentDateTimeStat = strCurrentYear + "-"+ strCurrentMonth_tmp
- + "-" + strCurrentDay + "_" + CurrentTimeStat;
- // End of Duration
- //Calculation of session start time and session end time
- sessionEndTime = CurrentTimeStat;
- sessionStartTime = (CString)_itoa(CurrentHour-DurationHour,buffer,10)+":"+ (CString)_itoa(CurrentMinute-DurationMinute,buffer,10)+":"+ (CString)_itoa(CurrentSecond-DurationSecond,buffer,10);
- sessionDate = strCurrentMonth_tmp + "/" + strCurrentDay + "/" + strCurrentYear;
- // Payload Type
-
- /*
- PCMU, // G.711 u-Law
- FS1016, // Federal Standard 1016 CELP
- G721, // ADPCM - Subsumed by G.726
- G726 = G721,
- GSM, // GSM 06.10
- G7231, // G.723.1 at 6.3kbps or 5.3 kbps
- DVI4_8k, // DVI4 at 8kHz sample rate
- DVI4_16k, // DVI4 at 16kHz sample rate
- LPC, // LPC-10 Linear Predictive CELP
- PCMA, // G.711 A-Law
- G722, // G.722
- L16_Stereo, // 16 bit linear PCM
- L16_Mono, // 16 bit linear PCM
- G723, // G.723
- CN, // Confort Noise
- MPA, // MPEG1 or MPEG2 audio
- G728, // G.728 16kbps CELP
- DVI4_11k, // DVI4 at 11kHz sample rate
- DVI4_22k, // DVI4 at 22kHz sample rate
- G729, // G.729 8kbps
- Cisco_CN, // Cisco systems comfort noise (unofficial)
- CelB = 25, // Sun Systems Cell-B video
- JPEG, // Motion JPEG
- H261 = 31, // H.261
- MPV, // MPEG1 or MPEG2 video
- MP2T, // MPEG2 transport system
- H263, // H.263
- */
- switch (atoi(PayloadTypeGlobal)){
- case 0: PayloadTypeName = "G.711 u-Law";
- break;
- case 1: PayloadTypeName = "Federal Standard 1016 CELP";
- break;
- case 2: PayloadTypeName = "ADPCM - Subsumed by G.726";
- break;
- case 3: PayloadTypeName = "GSM 06.10";
- break;
- case 4: PayloadTypeName = "G.723.1 at 6.3kbps or 5.3 kbps";
- break;
- case 5: PayloadTypeName = "GDVI4 at 8kHz sample rate";
- break;
- case 6: PayloadTypeName = "DVI4 at 16kHz sample rate";
- break;
- case 7: PayloadTypeName = "LPC-10 Linear Predictive CELP";
- break;
- case 8: PayloadTypeName = "G.711 A-Law";
- break;
- case 9: PayloadTypeName = "G.722";
- break;
- case 10:PayloadTypeName = "16 bit linear PCM";
- break;
- case 11:PayloadTypeName = "16 bit linear PCM";
- break;
- case 12:PayloadTypeName = "G.723";
- break;
- case 13:PayloadTypeName = "Confort Noise";
- break;
- case 14:PayloadTypeName = "MPEG1 or MPEG2 audio";
- break;
- case 15:PayloadTypeName = "G.728 16kbps CELP";
- break;
- case 16:PayloadTypeName = "DVI4 at 11kHz sample rate";
- break;
- case 17:PayloadTypeName = "DVI4 at 22kHz sample rate";
- break;
- case 18:PayloadTypeName = "G.729 8kbps";
- break;
- case 19:PayloadTypeName = "Cisco systems comfort noise (unofficial)";
- break;
- case 20:PayloadTypeName = "Sun Systems Cell-B video";
- break;
- case 21:PayloadTypeName = "Motion JPEG";
- break;
- case 22:PayloadTypeName = "H.261";
- break;
- case 23:PayloadTypeName = "MPEG1 or MPEG2 video";
- break;
- case 24:PayloadTypeName = "MPEG2 transport system";
- break;
- case 25:PayloadTypeName = "H.263";
- break;
- default:PayloadTypeName = "Unknown";
- }
- // end Payload Type
- // Call Date and Timestamp
- if (FlagEndPoint == 0){
- p_StartTime->SetWindowText(StartTime);
- p_StartTime->UpdateWindow();
-
- if (fs1.is_open()){
- fs1 << CurrentDateTimeStat << "n";
- fs1.close();
- }
- }
- // Payload Type
- p_PayloadType->SetWindowText(PayloadTypeName);
- p_PayloadType->UpdateWindow();
- if (fs2.is_open()){
- fs2 << PayloadTypeName << "n";
- fs2.close();
- }
- // Packet Lost
- str = _itoa(PacketsLostGlobal,buffer,10);
- p_PacketLoss->SetWindowText(str);
- p_PacketLoss->UpdateWindow();
- if (fs3.is_open()){
- fs3 << str << "n";
- fs3.close();
- }
- //GNUPlot related files
- tmpStrVar = CurrentDateTimeStat + " " + str + " " + pktlost_good + " " + pktlost_acceptable + " " + pktlost_unacceptable;
- if (fs3gplot.is_open()) {
- fs3gplot << tmpStrVar << "n";
- fs3gplot.close();
- }
- // Audio Jitter
- str = _itoa(JitterTimeGlobal,buffer,10);
- p_AudioJitter->SetWindowText(str);
- p_AudioJitter->UpdateWindow();
- if (fs4.is_open()){
- fs4 << str << "n";
- fs4.close();
- }
- //GNUPlot related file
- tmpStrVar = CurrentDateTimeStat + " " + str + " " + audjitter_good + " " + audjitter_acceptable + " " + audjitter_unacceptable;
- if (fs4gplot.is_open()){
- fs4gplot << tmpStrVar << "n";
- fs4gplot.close();
- }
- // Round Trip Delay
- CDlgStatistics::Ping(ipglobal);
-
- //str = _itoa(pingresult,buffer,10);
- str = _itoa(RoundTripTimeDelayGlobal,buffer,10);
- p_RoundTripDelay->SetWindowText(str);
- p_RoundTripDelay->UpdateWindow();
- if (fs5.is_open()){
- fs5 << str << "n";
- fs5.close();
- }
- //GNUPlot related file
- tmpStrVar = CurrentDateTimeStat + " " + str + " " + rtd_good + " " + rtd_acceptable + " " + rtd_unacceptable;
- if (fs5gplot.is_open()){
- fs5gplot << tmpStrVar << "n";
- fs5gplot.close();
- }
- // Packet Sent
- str = _itoa(PacketSentGlobal,buffer,10);
- p_PacketSent->SetWindowText(str);
- p_PacketSent->UpdateWindow();
- if (fs6.is_open()){
- fs6 << str << "n";
- fs6.close();
- }
-
- // Octet Sent
- str = _itoa(OctetSendGlobal,buffer,10);
- p_OctetSend->SetWindowText(str);
- p_OctetSend->UpdateWindow();
- if (fs7.is_open()){
- fs7 << str << "n";
- fs7.close();
- }
- // Packet Received
- str = _itoa(PacketsReceivedGlobal,buffer,10);
- p_PacketReceived->SetWindowText(str);
- p_PacketReceived->UpdateWindow();
- if (fs8.is_open()){
- fs8 << str << "n";
- fs8.close();
- }
- // Octet Received
- str = _itoa(OctetsReceivedGlobal,buffer,10);
- p_OctetReceived->SetWindowText(str);
- p_OctetReceived->UpdateWindow();
- if (fs9.is_open()){
- fs9 << str << "n";
- fs9.close();
- }
-
- // Server IP
- p_ServerIP->SetWindowText(ipglobal);
- p_ServerIP->UpdateWindow();
- // Client IP
- p_ClientIP->SetWindowText(localmachine);
- p_ClientIP->UpdateWindow();
- p_PayloadType->SetWindowText(PayloadTypeName);
- p_PayloadType->UpdateWindow();
-
- CDialog::OnTimer(nIDEvent);
- }
- else{
- CWnd::KillTimer(ConnectionTimer);
- CDlgStatistics::KillTimer(StatisticTimer);
-
-
- if (is_MsgBox_Display == 1){
- // Message Box globalEndReason has been displayed
- }
- else{
- if (globalEndReason = "") {
- // Do Nothing
- }
- else{
-
- }
-
- }
-
-
- FlagEndPoint = 1;
- } /// stat == 0
- } //globalinstance->endpoint
- else{
- FlagEndPoint = 1;
- }
- } // End TRY
- CATCH_ALL(e){
- // Put some delay here
- }
- END_CATCH_ALL
- }
- int CDlgStatistics::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CDialog::OnCreate(lpCreateStruct) == -1)
- return -1;
-
- // TODO: Add your specialized creation code here
-
- return 0;
- }
- // New addition for ping command
- // Ping()
- // Calls SendEchoRequest() and
- // RecvEchoReply() and prints results
- void CDlgStatistics::Ping(LPCSTR pstrHost)
- {
- SOCKET rawSocket;
- LPHOSTENT lpHost;
- struct sockaddr_in saDest;
- struct sockaddr_in saSrc;
- DWORD dwTimeSent;
- DWORD dwElapsed;
- u_char cTTL;
- int nLoop;
- int nRet;
- // Create a Raw socket
- rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- if (rawSocket == SOCKET_ERROR) {
- ReportError("socket()");
- return;
- }
-
- // Lookup host
- lpHost = gethostbyname(pstrHost);
- if (lpHost == NULL){
-
- return;
- }
-
- // Setup destination socket address
- saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
- saDest.sin_family = AF_INET;
- saDest.sin_port = 0;
- // Ping multiple times
- for (nLoop = 0; nLoop < 1; nLoop++){
- // Send ICMP echo request
- CDlgStatistics::SendEchoRequest(rawSocket, &saDest);
- // Use select() to wait for data to be received
- nRet = CDlgStatistics::WaitForEchoReply(rawSocket);
- if (nRet == SOCKET_ERROR){
- ReportError("select()");
- break;
- }
- if (!nRet){
- printf("nTimeOut");
- break;
- }
- // Receive reply
- dwTimeSent = CDlgStatistics::RecvEchoReply(rawSocket, &saSrc, &cTTL);
- // Calculate elapsed time
- dwElapsed = GetTickCount() - dwTimeSent;
- pingresult = dwElapsed;
- if (pingresult != 0){
- int a123 = 0;
- }
-
- }
-
- nRet = closesocket(rawSocket);
- if (nRet == SOCKET_ERROR)
- {
- // Do nothing
- ReportError("closesocket()");
- }
- }
- // SendEchoRequest()
- // Fill in echo request header
- // and send to destination
- int CDlgStatistics::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
- {
- static ECHOREQUEST echoReq;
- static nId = 1;
- static nSeq = 1;
- int nRet;
- // Fill in echo request
- echoReq.icmpHdr.Type = ICMP_ECHOREQ;
- echoReq.icmpHdr.Code = 0;
- echoReq.icmpHdr.Checksum = 0;
- echoReq.icmpHdr.ID = nId++;
- echoReq.icmpHdr.Seq = nSeq++;
- // Fill in some data to send
- for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
- echoReq.cData[nRet] = ' '+nRet;
- // Save tick count when sent
- echoReq.dwTime = GetTickCount();
- // Put data in packet and compute checksum
- echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));
- // Send the echo request
- nRet = sendto(s, /* socket */
- (LPSTR)&echoReq, /* buffer */
- sizeof(ECHOREQUEST),
- 0, /* flags */
- (LPSOCKADDR)lpstToAddr, /* destination */
- sizeof(SOCKADDR_IN)); /* address length */
- if (nRet == SOCKET_ERROR){
- // Do nothing
- ReportError("sendto()");
- }
- return (nRet);
- }
- // RecvEchoReply()
- // Receive incoming data
- // and parse out fields
- DWORD CDlgStatistics::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)
- {
- ECHOREPLY echoReply;
- int nRet;
- int nAddrLen = sizeof(struct sockaddr_in);
- // Receive the echo reply
- nRet = recvfrom(s, // socket
- (LPSTR)&echoReply, // buffer
- sizeof(ECHOREPLY), // size of buffer
- 0, // flags
- (LPSOCKADDR)lpsaFrom, // From address
- &nAddrLen); // pointer to address len
- // Check return value
- if (nRet == SOCKET_ERROR){
- // Do Nothing
- ReportError("recvfrom()");
- }
- // return time sent and IP TTL
- *pTTL = echoReply.ipHdr.TTL;
- return(echoReply.echoRequest.dwTime);
- }
- // What happened?
- void CDlgStatistics::ReportError(LPCSTR pWhere)
- {
- fprintf(stderr,"n%s error: %dn",
- WSAGetLastError());
- }
- // WaitForEchoReply()
- // Use select() to determine when
- // data is waiting to be read
- int CDlgStatistics::WaitForEchoReply(SOCKET s)
- {
- struct timeval Timeout;
- fd_set readfds;
- readfds.fd_count = 1;
- readfds.fd_array[0] = s;
- Timeout.tv_sec = 5;
- Timeout.tv_usec = 0;
- return(select(1, &readfds, NULL, NULL, &Timeout));
- }
- //
- // Mike Muuss' in_cksum() function
- // and his comments from the original
- // ping program
- //
- // * Author -
- // * Mike Muuss
- // * U. S. Army Ballistic Research Laboratory
- // * December, 1983
- /*
- * I N _ C K S U M
- *
- * Checksum routine for Internet Protocol family headers (C Version)
- *
- */
- u_short CDlgStatistics::in_cksum(u_short *addr, int len)
- {
- register int nleft = len;
- register u_short *w = addr;
- register u_short answer;
- register int sum = 0;
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum),
- * we add sequential 16 bit words to it, and at the end, fold
- * back all the carry bits from the top 16 bits into the lower
- * 16 bits.
- */
- while( nleft > 1 ) {
- sum += *w++;
- nleft -= 2;
- }
- /* mop up an odd byte, if necessary */
- if( nleft == 1 ) {
- u_short u = 0;
- *(u_char *)(&u) = *(u_char *)w ;
- sum += u;
- }
- /*
- * add back carry outs from top 16 bits to low 16 bits
- */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return (answer);
- }