📄 cresponse.cpp
字号:
#include "CResponse.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef _WIN32
#pragma comment(lib,"wsock32.lib ")
#endif
#define TIME_OUT -1
#define UNIVERSALITY_ERROR -2
u_short 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);
}
int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr)
{
static ECHOREQUEST echoReq;
static int nId = 1;
static int 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
#ifdef WIN32
echoReq.dwTime = GetTickCount();
#else
struct timeval tvsend;
gettimeofday(&tvsend, 0);
// printf("%d %d\n",tvsend.tv_sec, tvsend.tv_usec);
echoReq.dwTime = tvsend.tv_sec*1000+tvsend.tv_usec/1000;
#endif
// 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 */
(char*)&echoReq, /* buffer */
sizeof(ECHOREQUEST),
0, /* flags */
(LPSOCKADDR)lpstToAddr, /* destination */
sizeof(SOCKADDR_IN)); /* address length */
return (nRet);
}
// int WaitForEchoReply(SOCKET s)
// {
//
// //readfds.fd_count = 1;
// //readfds.fd_array[0] = s;
// struct timeval Timeout;
// fd_set readfds;
//
// Timeout.tv_sec = 1;
// Timeout.tv_usec = 0;
//
// bool loop = true;
// while(loop)
// {
// FD_ZERO(&readfds);
// FD_SET(s, &readfds);
//
//
// int ret = select(s+1, &readfds, NULL, NULL, &Timeout);
// if( ret==0 )
// return 0;
//
// //if(FD_ISSET(s, &readfds))
// // return 1;
// }
//
// return 0;
// }
int RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL, char* ipAddress)
{
struct timeval timeout;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET (s, &readfds);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
while(true)
{
switch(select(s+1,&readfds,NULL,NULL,&timeout))
{
case -1: continue;// return UNIVERSALITY_ERROR;
case 0: return TIME_OUT;
// default:
// if (FD_ISSET(s,&readfds))
// {
// break;
// }
//
}
ECHOREPLY echoReply;
int nRet;
#ifdef WIN32
int nAddrLen;
#else
socklen_t nAddrLen;
#endif
nAddrLen = sizeof(struct sockaddr_in);
// Receive the echo reply
nRet = recvfrom(s, // socket
(char*)&echoReply, // buffer
sizeof(ECHOREPLY), // size of buffer
0, // flags
(LPSOCKADDR)lpsaFrom, // From address
&nAddrLen); // pointer to address len
if(nRet==-1)
{
return UNIVERSALITY_ERROR;
}
// Check return value
if(strcmp(ipAddress, inet_ntoa(lpsaFrom->sin_addr))!=0)
return UNIVERSALITY_ERROR;
// continue;
// return time sent and IP TTL
*pTTL = echoReply.ipHdr.TTL;
return(echoReply.echoRequest.dwTime);
}
return UNIVERSALITY_ERROR;
}
#if (CRESPONSE)
JNIEXPORT jintArray JNICALL Java_com_qwserv_itm_util_protocol_RemotePing_CResponse_GetTime(JNIEnv *env, jobject obj, jstring s, jint rcount)
{
SOCKET rawSocket;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
int nRet;
DWORD dwTimeSent=0,dwElapsed=0;
u_char cTTL;
long m_laddr;
char tmpStr[256];
int PingRetries = rcount;
//int upTimes, downTimes;
int responseTime=0, avail=0, percentLoss=0;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 0;
}
#endif
const char* ipAddress = env->GetStringUTFChars(s, 0);
m_laddr = inet_addr((char*)ipAddress);
saDest.sin_addr.s_addr = m_laddr;
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
sprintf(tmpStr, "Pinging %s [%s] with %d bytes of data:",
ipAddress,
inet_ntoa(saDest.sin_addr),
REQ_DATASIZE);
long success = 0;
long count = 0;
long retval = 0;
long istimeout =0;
for (int nLoop=0; nLoop<PingRetries; nLoop++)
{
count++;
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
nRet = SendEchoRequest(rawSocket, &saDest);
if(nRet==-1)
{
PingRetries+=1;
nRet = closesocket(rawSocket);
continue;
}
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL, (char*)ipAddress);
nRet = closesocket(rawSocket);
if (dwTimeSent==TIME_OUT)
{
char tmp[256];
sprintf(tmp, "[%s] timeout!", ipAddress);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
istimeout=1;
continue;
}
if (dwTimeSent==UNIVERSALITY_ERROR)
{
char tmp[256];
sprintf(tmp, "[%s] UNIVERSALITY_ERROR", ipAddress);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
PingRetries+=1;
count--;
continue;
}
#ifdef WIN32
dwElapsed = GetTickCount() - dwTimeSent;
#else
struct timeval tvrecv;
gettimeofday(&tvrecv, 0);
printf("%d %d\n", tvrecv.tv_sec, tvrecv.tv_usec);
dwElapsed = tvrecv.tv_sec*1000+tvrecv.tv_usec/1000-dwTimeSent;
#endif
sprintf(tmpStr, "Reply[%d] from: %s: bytes=%d time=%ldms TTL=%d",
nLoop+1,
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
dwElapsed,
cTTL);
if (dwElapsed>3000)
{
continue;
}
success=1;
break;
}
if(success==0)
{
percentLoss=100;
// if(istimeout==1)
responseTime=-1;
// else
// responseTime=0;
avail = 0;
}
else
{
avail = 100;
responseTime = dwElapsed;
percentLoss = (count-1)*100/count;
}
int retv[3];
jintArray arr = env->NewIntArray(3);
retv[0] = responseTime;
retv[1] = avail;
retv[2] = percentLoss;
env->ReleaseStringUTFChars(s, ipAddress);
env->SetIntArrayRegion(arr, 0, 3, (jint *)retv);
#ifdef _WIN32
WSACleanup( );
#endif
return arr;
}
#endif
#if (!CRESPONSE)
int main(int argc,char *argv[])
{
if(argc<=2)
{
printf("Help MP\n");
printf("-i ipaddress\n");
printf("-rc count number\n");
// printf("-ps send pack size\n");
// printf("-log output log file\n");
printf("linux ./mp -i 192.168.1.1 -rc 1000 \n");
return 0;
}
SOCKET rawSocket;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
int nRet;
DWORD dwTimeSent,dwElapsed;
u_char cTTL;
long m_laddr;
char tmpStr[256];
int rcount =1;
char ipAddress[32] = {"\0"};
char szLogFile[256];
int nps = 32;
FILE* fe=NULL;
for(int i=0;i<argc;i++)
{
if(strcmp("-i",argv[i])==0)
{
strcpy(ipAddress,argv[i+1]);
}
else if(strcmp("-rc",argv[i])==0)
{
rcount = atoi(argv[i+1]);
}
else if(strcmp("-ps",argv[i])==0)
{
nps = atoi(argv[i+1]);
}
else if(strcmp("-log",argv[i])==0)
{
strcpy(szLogFile,argv[i+1]);
fe = fopen(szLogFile,"ta");
if(!fe)
{
printf("create file %s is faile\n",szLogFile);
}
}
}
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 0;
}
#endif
int PingRetries = rcount;
int responseTime, avail, percentLoss;
m_laddr = inet_addr((char*)ipAddress);
saDest.sin_addr.s_addr = m_laddr;
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
sprintf(tmpStr, "Pinging %s [%s] with %d bytes of data:",
ipAddress,
inet_ntoa(saDest.sin_addr),
REQ_DATASIZE);
printf("%s\n",tmpStr);
long success = 0;
long count = 0;
long retval = 0;
for (int nLoop=0; nLoop<PingRetries; nLoop++)
{
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
nRet = SendEchoRequest(rawSocket, &saDest);
if(nRet==SOCKET_ERROR)
{
PingRetries+=1;
nRet = closesocket(rawSocket);
continue;
}
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL, (char*)ipAddress);
nRet = closesocket(rawSocket);
if (dwTimeSent==TIME_OUT)
{
char tmp[256];
sprintf(tmp, "[%s] timeout!\n", ipAddress);
printf(tmp);
if(fe) fwrite(tmp,strlen(tmp),1,fe);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
continue;
}
#ifdef WIN32
dwElapsed = GetTickCount() - dwTimeSent;
#else
struct timeval tvrecv;
gettimeofday(&tvrecv, 0);
dwElapsed = tvrecv.tv_sec*1000+tvrecv.tv_usec/1000-dwTimeSent;
#endif
sprintf(tmpStr, "Reply[%d] from: %s: bytes=%d time=%ldms TTL=%d",
nLoop+1,
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
dwElapsed,
cTTL);
printf("%s\n", tmpStr);
if (dwElapsed>3000)
continue;
success=1;
count++;
#ifndef WIN32
sleep(1);
#endif
}
#ifdef _WIN32
WSACleanup( );
#endif
return 0;
}
#endif
#if (CRESPONSE)
#ifdef _WIN32
#define EXPORT extern "C" __declspec(dllexport)
#else
#define EXPORT
#endif
EXPORT int ping(const char* s, int rcount,int* r1,int* r2,int* r3)
{
SOCKET rawSocket;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
int nRet;
DWORD dwTimeSent=0,dwElapsed=0;
u_char cTTL;
long m_laddr;
char tmpStr[256];
int PingRetries = rcount;
//int upTimes, downTimes;
int responseTime=0, avail=0, percentLoss=0;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 0;
}
#endif
const char* ipAddress = s;
m_laddr = inet_addr((char*)ipAddress);
saDest.sin_addr.s_addr = m_laddr;
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
sprintf(tmpStr, "Pinging %s [%s] with %d bytes of data:",
ipAddress,
inet_ntoa(saDest.sin_addr),
REQ_DATASIZE);
long success = 0;
long count = 0;
long retval = 0;
long istimeout =0;
for (int nLoop=0; nLoop<PingRetries; nLoop++)
{
count++;
printf("socket\n");
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
printf("SendEchoRequest\n");
nRet = SendEchoRequest(rawSocket, &saDest);
if(nRet==-1)
{
printf("SendEchoRequest return -1 count=%d nLoop=%d PingRetries=%d\n",count,nLoop,PingRetries);
nRet = closesocket(rawSocket);
continue;
}
printf("RecvEchoReply\n");
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL, (char*)ipAddress);
printf("RecvEchoReply end\n");
nRet = closesocket(rawSocket);
if (dwTimeSent==TIME_OUT)
{
char tmp[256];
sprintf(tmp, "[%s] timeout!", ipAddress);
printf("%s\n",tmp);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
istimeout=1;
continue;
}
if (dwTimeSent==UNIVERSALITY_ERROR)
{
char tmp[256];
sprintf(tmp, "[%s] UNIVERSALITY_ERROR", ipAddress);
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
PingRetries+=1;
count--;
continue;
}
#ifdef WIN32
dwElapsed = GetTickCount() - dwTimeSent;
#else
struct timeval tvrecv;
gettimeofday(&tvrecv, 0);
printf("%d %d\n", tvrecv.tv_sec, tvrecv.tv_usec);
dwElapsed = tvrecv.tv_sec*1000+tvrecv.tv_usec/1000-dwTimeSent;
#endif
sprintf(tmpStr, "Reply[%d] from: %s: bytes=%d time=%ldms TTL=%d",
nLoop+1,
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
dwElapsed,
cTTL);
printf("%s\n",tmpStr);
if (dwElapsed>3000)
{
continue;
}
success=1;
break;
}
if(success==0)
{
percentLoss=100;
// if(istimeout==1)
responseTime=-1;
// else
// responseTime=0;
avail = 0;
}
else
{
avail = 100;
responseTime = dwElapsed;
percentLoss = (count-1)*100/count;
}
*r1 = responseTime;
*r2 = avail;
*r3 = percentLoss;
#ifdef _WIN32
WSACleanup( );
#endif
return nRet;
}
int main(int argc,char *argv[])
{
int ret =0;
int r1=0;
int r2=0;
int r3=0;
ret = ping(argv[1],10,&r1,&r2,&r3);
printf("[%d] [%d] [%d]\n",r1,r2,r3);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -