R
RoyT
Unregistered / Unconfirmed
GUEST, unregistred user!
我本人不是学c的,对网络这部分更是难理解。今拿到一段代码,欲知道每行的意思,求哪位高手给解答一下。希望尽量把有函数的地方表明一下什么意思!不胜感激
#include <stdio.h>
#include "Ping.h"
#include "com_adminet_protocol_icmp_winPing.h"
/*
* Checksum routine for Internet Protocol family headers (C Version)
*/
unsigned short CPing::in_cksum(unsigned 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;
*(unsigned char *)(&u) = *(unsigned 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 CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr,int nData)
{
ECHOREQUEST echoReq;
int nId = 1;
int nSeq = 1;
int nRet;
char* cData=(char*)malloc(nData);
// Fill in echo request
echoReq.icmpHdr.Type = ICMP_ECHOREQ;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.Checksum = 0;
echoReq.icmpHdr.ID = (USHORT)GetCurrentThreadId();
echoReq.icmpHdr.Seq = (USHORT)GetCurrentProcessId();
// Fill in some data to send
for (nRet = 0;
nRet < nData;
nRet++)
cData[nRet] = ' '+nRet;
echoReq.cData=cData;
// 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 */
free(cData);
if (nRet == SOCKET_ERROR)
return -1;
return (nRet);
}
DWORD CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, unsigned 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)
return 0;
if (echoReply.echoRequest.icmpHdr.ID!=(USHORT)GetCurrentThreadId())
return 0;
if (echoReply.echoRequest.icmpHdr.Seq!=(USHORT)GetCurrentProcessId())
return 0;
// return time sent and IP TTL
*pTTL = echoReply.ipHdr.TTL;
return(echoReply.echoRequest.dwTime);
}
int CPing::OpenRawSocket()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
return -1;
// WSAStartup error!
}
// Create a Raw socket
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR)
{
return 0;
}
return 1;
}
int CPing::CloseRawSocket()
{
int nRet;
if (rawSocket != INVALID_SOCKET)
nRet=closesocket(rawSocket);
if (nRet == SOCKET_ERROR)
return 0;
WSACleanup();
return 1;
}
int CPing::IcmpPing(LPCSTR pstrHost,int nTimeOut,int nData, char szResult[256])
{
PHOSTENT lpHost;
int nRet;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
unsigned char cTTL;
if (rawSocket == INVALID_SOCKET)
return -1;
if (nData<=0)
nData=REQ_DATASIZE;
if (nTimeOut<=0)
nTimeOut=1000;
/*
nRet = setsockopt(rawSocket,
SOL_SOCKET,
SO_SNDTIMEO,
(char*)&nTimeOut,
sizeof(nTimeOut));
if(nRet == SOCKET_ERROR)
{
return -1;
}
*/
// Lookup host
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL)
{
return -1;
}
// Setup destination socket address
saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
// Send ICMP echo request
SendEchoRequest(rawSocket, &saDest,nData);
int nTimeOutTemp=nTimeOut;
struct timeval Timeout;
fd_set readfds;
readfds.fd_count = 1;
readfds.fd_array[0] = rawSocket;
while(nTimeOutTemp>0)
{
Timeout.tv_sec = nTimeOutTemp/1000;
Timeout.tv_usec = nTimeOutTemp;
dwElapsed=GetTickCount();
nRet=select(1, &readfds, NULL, NULL, &Timeout);
if (nRet == SOCKET_ERROR)
{
return -1;
}
if (!nRet)
{
//Request time out
break;
}
else
{
// Receive reply
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
dwElapsed = GetTickCount() - dwElapsed;
if (dwTimeSent>0)
{
sprintf(szResult,"Reply from: %s: bytes=%d time=%ldms TTL=%d",
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
GetTickCount()-dwTimeSent,
cTTL);
return 1;
}
else
{
nTimeOutTemp=nTimeOutTemp-dwElapsed;
continue;
}
}
}
sprintf(szResult,"Request timed out!");
return 0;
}
int CPing:ing(LPCSTR pstrHost,int nRetries,int nTimeOut)
{
SOCKET rawIcmpSocket;
LPHOSTENT lpHost;
int nLoop;
int nRet;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
unsigned char cTTL;
int nData=REQ_DATASIZE;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
return -1;
// WSAStartup error!
}
if (nTimeOut<=0)
nTimeOut=1000;
// Create a Raw socket
rawIcmpSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawIcmpSocket == INVALID_SOCKET)
{
WSACleanup();
return -1;
}
/*
nRet = setsockopt(rawIcmpSocket,
SOL_SOCKET,
SO_SNDTIMEO,
(char*)&nTimeOut,
sizeof(nTimeOut));
if(nRet == SOCKET_ERROR)
{
return -1;
}
*/
// Lookup host
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL)
{
closesocket(rawIcmpSocket);
WSACleanup();
return -1;
}
// 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 < nRetries;
nLoop++)
{
// Send ICMP echo request
SendEchoRequest(rawIcmpSocket, &saDest,nData);
struct timeval Timeout;
fd_set readfds;
readfds.fd_count = 1;
readfds.fd_array[0] = rawIcmpSocket;
int nTimeOutTemp=nTimeOut;
while(nTimeOutTemp>0)
{
Timeout.tv_sec = nTimeOutTemp/1000;
Timeout.tv_usec = nTimeOutTemp;
dwElapsed=GetTickCount();
nRet=select(1, &readfds, NULL, NULL, &Timeout);
if (nRet == SOCKET_ERROR)
{
closesocket(rawIcmpSocket);
WSACleanup();
return -1;
}
if (!nRet)
{
//Request time out
break;
}
else
{
// Receive reply
dwTimeSent = RecvEchoReply(rawIcmpSocket, &saSrc, &cTTL);
dwElapsed = GetTickCount() - dwElapsed;
if (dwTimeSent>0)
{
closesocket(rawIcmpSocket);
WSACleanup();
return 1;
}
else
{
nTimeOutTemp=nTimeOutTemp-dwElapsed;
continue;
}
}
}
}
closesocket(rawIcmpSocket);
WSACleanup();
return 0;
}
/*
* Class: com_winPing
* Method: ping
* Signature: (Ljava/lang/StringI
*/
JNIEXPORT jint JNICALL Java_com_adminet_protocol_icmp_winPing_ping__Ljava_lang_String_2
(JNIEnv * env, jobject obj, jstring IP)
{
CPing ping;
const char* szIP=env->GetStringUTFChars(IP,0);
return ping.Ping((LPCSTR)szIP,3,1000);
}
/*
* Class: com_dcnetworks_protocol_icmp_IcmpPing
* Method: simplePing
* Signature: (Ljava/lang/String;II)I
*/
JNIEXPORT jint JNICALL Java_com_adminet_protocol_icmp_winPing_ping__Ljava_lang_String_2II
(JNIEnv* env, jobject obj, jstring IP, jint retrys, jint timeout)
{
if (retrys<1)
retrys=3;
if (timeout<1)
timeout=1000;
CPing ping;
const char* szIP=env->GetStringUTFChars(IP,0);
return ping.Ping((LPCSTR)szIP,(int)retrys,(int)timeout);
}
#include <stdio.h>
#include "Ping.h"
#include "com_adminet_protocol_icmp_winPing.h"
/*
* Checksum routine for Internet Protocol family headers (C Version)
*/
unsigned short CPing::in_cksum(unsigned 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;
*(unsigned char *)(&u) = *(unsigned 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 CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr,int nData)
{
ECHOREQUEST echoReq;
int nId = 1;
int nSeq = 1;
int nRet;
char* cData=(char*)malloc(nData);
// Fill in echo request
echoReq.icmpHdr.Type = ICMP_ECHOREQ;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.Checksum = 0;
echoReq.icmpHdr.ID = (USHORT)GetCurrentThreadId();
echoReq.icmpHdr.Seq = (USHORT)GetCurrentProcessId();
// Fill in some data to send
for (nRet = 0;
nRet < nData;
nRet++)
cData[nRet] = ' '+nRet;
echoReq.cData=cData;
// 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 */
free(cData);
if (nRet == SOCKET_ERROR)
return -1;
return (nRet);
}
DWORD CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, unsigned 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)
return 0;
if (echoReply.echoRequest.icmpHdr.ID!=(USHORT)GetCurrentThreadId())
return 0;
if (echoReply.echoRequest.icmpHdr.Seq!=(USHORT)GetCurrentProcessId())
return 0;
// return time sent and IP TTL
*pTTL = echoReply.ipHdr.TTL;
return(echoReply.echoRequest.dwTime);
}
int CPing::OpenRawSocket()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
return -1;
// WSAStartup error!
}
// Create a Raw socket
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR)
{
return 0;
}
return 1;
}
int CPing::CloseRawSocket()
{
int nRet;
if (rawSocket != INVALID_SOCKET)
nRet=closesocket(rawSocket);
if (nRet == SOCKET_ERROR)
return 0;
WSACleanup();
return 1;
}
int CPing::IcmpPing(LPCSTR pstrHost,int nTimeOut,int nData, char szResult[256])
{
PHOSTENT lpHost;
int nRet;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
unsigned char cTTL;
if (rawSocket == INVALID_SOCKET)
return -1;
if (nData<=0)
nData=REQ_DATASIZE;
if (nTimeOut<=0)
nTimeOut=1000;
/*
nRet = setsockopt(rawSocket,
SOL_SOCKET,
SO_SNDTIMEO,
(char*)&nTimeOut,
sizeof(nTimeOut));
if(nRet == SOCKET_ERROR)
{
return -1;
}
*/
// Lookup host
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL)
{
return -1;
}
// Setup destination socket address
saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
// Send ICMP echo request
SendEchoRequest(rawSocket, &saDest,nData);
int nTimeOutTemp=nTimeOut;
struct timeval Timeout;
fd_set readfds;
readfds.fd_count = 1;
readfds.fd_array[0] = rawSocket;
while(nTimeOutTemp>0)
{
Timeout.tv_sec = nTimeOutTemp/1000;
Timeout.tv_usec = nTimeOutTemp;
dwElapsed=GetTickCount();
nRet=select(1, &readfds, NULL, NULL, &Timeout);
if (nRet == SOCKET_ERROR)
{
return -1;
}
if (!nRet)
{
//Request time out
break;
}
else
{
// Receive reply
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
dwElapsed = GetTickCount() - dwElapsed;
if (dwTimeSent>0)
{
sprintf(szResult,"Reply from: %s: bytes=%d time=%ldms TTL=%d",
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
GetTickCount()-dwTimeSent,
cTTL);
return 1;
}
else
{
nTimeOutTemp=nTimeOutTemp-dwElapsed;
continue;
}
}
}
sprintf(szResult,"Request timed out!");
return 0;
}
int CPing:ing(LPCSTR pstrHost,int nRetries,int nTimeOut)
{
SOCKET rawIcmpSocket;
LPHOSTENT lpHost;
int nLoop;
int nRet;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
unsigned char cTTL;
int nData=REQ_DATASIZE;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
return -1;
// WSAStartup error!
}
if (nTimeOut<=0)
nTimeOut=1000;
// Create a Raw socket
rawIcmpSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawIcmpSocket == INVALID_SOCKET)
{
WSACleanup();
return -1;
}
/*
nRet = setsockopt(rawIcmpSocket,
SOL_SOCKET,
SO_SNDTIMEO,
(char*)&nTimeOut,
sizeof(nTimeOut));
if(nRet == SOCKET_ERROR)
{
return -1;
}
*/
// Lookup host
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL)
{
closesocket(rawIcmpSocket);
WSACleanup();
return -1;
}
// 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 < nRetries;
nLoop++)
{
// Send ICMP echo request
SendEchoRequest(rawIcmpSocket, &saDest,nData);
struct timeval Timeout;
fd_set readfds;
readfds.fd_count = 1;
readfds.fd_array[0] = rawIcmpSocket;
int nTimeOutTemp=nTimeOut;
while(nTimeOutTemp>0)
{
Timeout.tv_sec = nTimeOutTemp/1000;
Timeout.tv_usec = nTimeOutTemp;
dwElapsed=GetTickCount();
nRet=select(1, &readfds, NULL, NULL, &Timeout);
if (nRet == SOCKET_ERROR)
{
closesocket(rawIcmpSocket);
WSACleanup();
return -1;
}
if (!nRet)
{
//Request time out
break;
}
else
{
// Receive reply
dwTimeSent = RecvEchoReply(rawIcmpSocket, &saSrc, &cTTL);
dwElapsed = GetTickCount() - dwElapsed;
if (dwTimeSent>0)
{
closesocket(rawIcmpSocket);
WSACleanup();
return 1;
}
else
{
nTimeOutTemp=nTimeOutTemp-dwElapsed;
continue;
}
}
}
}
closesocket(rawIcmpSocket);
WSACleanup();
return 0;
}
/*
* Class: com_winPing
* Method: ping
* Signature: (Ljava/lang/StringI
*/
JNIEXPORT jint JNICALL Java_com_adminet_protocol_icmp_winPing_ping__Ljava_lang_String_2
(JNIEnv * env, jobject obj, jstring IP)
{
CPing ping;
const char* szIP=env->GetStringUTFChars(IP,0);
return ping.Ping((LPCSTR)szIP,3,1000);
}
/*
* Class: com_dcnetworks_protocol_icmp_IcmpPing
* Method: simplePing
* Signature: (Ljava/lang/String;II)I
*/
JNIEXPORT jint JNICALL Java_com_adminet_protocol_icmp_winPing_ping__Ljava_lang_String_2II
(JNIEnv* env, jobject obj, jstring IP, jint retrys, jint timeout)
{
if (retrys<1)
retrys=3;
if (timeout<1)
timeout=1000;
CPing ping;
const char* szIP=env->GetStringUTFChars(IP,0);
return ping.Ping((LPCSTR)szIP,(int)retrys,(int)timeout);
}