这是以前自己写的Ping代码, 以ICMP协议为基础
ICMP协议参考: http://baike.baidu.com/view/30564.htm
--------------------------------------------------------------------------------------------------------------------------------------------------
#define ICMP_ECHO 8
#define ICMP_REPLAY 0
#define MAX_DATA_SIZE 32
#define ICMP_MIN 8
#pragma pack(1)
typedef struct tagICMPHeader
{
UCHAR type;
UCHAR code;
USHORT checkSum;
USHORT ID;
USHORT SeqNumber;
}ICMPHeader, *PICMPHeader;
#pragma pack()
#endif // ICMP_H
#pragma pack(1)
typedef struct tagPingPacket
{
ICMPHeader icmp_header;
DWORD dwTime;
}PingPacket, *PPingPacket;
#pragma pack()
ICMP协议参考: http://baike.baidu.com/view/30564.htm
--------------------------------------------------------------------------------------------------------------------------------------------------
//Please link library WS2_32.LIB at first.
// ICMP.h
#include <windows.h>
#ifndef __ICMP_H__
#define __ICMP_H__
#ifndef __ICMP_H__
#define __ICMP_H__
#define ICMP_ECHO 8
#define ICMP_REPLAY 0
#define MAX_DATA_SIZE 32
#define ICMP_MIN 8
#pragma pack(1)
typedef struct tagICMPHeader
{
UCHAR type;
UCHAR code;
USHORT checkSum;
USHORT ID;
USHORT SeqNumber;
}ICMPHeader, *PICMPHeader;
#pragma pack()
#pragma pack(1)
typedef struct tagIPHeader
{
BYTE h_len:4;
BYTE version:4;
BYTE tos;
USHORT total_len;
USHORT ID;
USHORT flags;
BYTE ttl;
BYTE proto;
USHORT checksum;
ULONG source_ip;
ULONG dest_ip;
}IPHeader, *PIPHeader;
#pragma pack()
typedef struct tagIPHeader
{
BYTE h_len:4;
BYTE version:4;
BYTE tos;
USHORT total_len;
USHORT ID;
USHORT flags;
BYTE ttl;
BYTE proto;
USHORT checksum;
ULONG source_ip;
ULONG dest_ip;
}IPHeader, *PIPHeader;
#pragma pack()
#endif // ICMP_H
// Ping.h
#include "ICMP.H"
#include <iostream>
using namespace std;
#include "ICMP.H"
#include <iostream>
using namespace std;
#ifndef __PING_H__
#define __PING_H__
#define __PING_H__
#pragma pack(1)
typedef struct tagPingPacket
{
ICMPHeader icmp_header;
DWORD dwTime;
}PingPacket, *PPingPacket;
#pragma pack()
class Ping
{
public:
Ping();
~Ping();
BOOL StartClient();
{
public:
Ping();
~Ping();
BOOL StartClient();
private:
void PackPingPacket(PingPacket& ping_packet);
int UnPackPingPacket();
int Configuration();
int ReceivePacket();
int SendPacket();
DWORD InitializeConnection();
int UnitializeConnection();
DecodePingPacket(const IPHeader& ip_header, const int recvPacketLen);
friend USHORT ip_checksum(USHORT* buffer, int size);
friend void ReadIPAddress(unsigned long IPAddress);
void PackPingPacket(PingPacket& ping_packet);
int UnPackPingPacket();
int Configuration();
int ReceivePacket();
int SendPacket();
DWORD InitializeConnection();
int UnitializeConnection();
DecodePingPacket(const IPHeader& ip_header, const int recvPacketLen);
friend USHORT ip_checksum(USHORT* buffer, int size);
friend void ReadIPAddress(unsigned long IPAddress);
private:
SOCKET sock;
sockaddr_in dest;
sockaddr_in source;
};
SOCKET sock;
sockaddr_in dest;
sockaddr_in source;
};
#endif // PING_H
PING.cpp
#include "PING.H"
const TCHAR* DEFAULT_ADDRESS = TEXT("220.181.27.48"); // LocalHost
const int TIMEOUT = 1000; // 1 second
const int TIMEOUT = 1000; // 1 second
Ping::Ping()
{
InitializeConnection();
}
{
InitializeConnection();
}
Ping::~Ping()
{
UnitializeConnection();
}
{
UnitializeConnection();
}
BOOL Ping::StartClient()
{
while(true)
{
if (SendPacket())
{
return FALSE;
}
if (ReceivePacket())
{
return FALSE;
}
Sleep(1000);
}
return TRUE;
}
{
while(true)
{
if (SendPacket())
{
return FALSE;
}
if (ReceivePacket())
{
return FALSE;
}
Sleep(1000);
}
return TRUE;
}
DWORD Ping::InitializeConnection()
{
cout << "Initialize Connection!" << endl;
WSAData wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
{
cout << "Startup error!" << endl;
return GetLastError();
}
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0)
{
cout << "Create socket error!" << endl;
return GetLastError();
}
if (Configuration())
{
return GetLastError();
}
return 0;
}
{
cout << "Initialize Connection!" << endl;
WSAData wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
{
cout << "Startup error!" << endl;
return GetLastError();
}
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0)
{
cout << "Create socket error!" << endl;
return GetLastError();
}
if (Configuration())
{
return GetLastError();
}
return 0;
}
int Ping::Configuration()
{
int ttl = TIMEOUT;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&ttl, sizeof(ttl)) == SOCKET_ERROR)
{
cout << "Error in Configuration, error code:" << GetLastError() << endl;
return GetLastError();
}
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr(DEFAULT_ADDRESS);
return 0;
}
{
int ttl = TIMEOUT;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&ttl, sizeof(ttl)) == SOCKET_ERROR)
{
cout << "Error in Configuration, error code:" << GetLastError() << endl;
return GetLastError();
}
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr(DEFAULT_ADDRESS);
return 0;
}
int Ping::UnitializeConnection()
{
WSACleanup();
closesocket(sock);
cout << "Unitialize Connection!" << endl;
return 0;
}
{
WSACleanup();
closesocket(sock);
cout << "Unitialize Connection!" << endl;
return 0;
}
void Ping::PackPingPacket(PingPacket& ping_packet)
{
static USHORT ID = 1;
static USHORT SeqNumber = 1;
ping_packet.icmp_header.type = ICMP_ECHO;
ping_packet.icmp_header.code = 0;
ping_packet.icmp_header.checkSum = 0;
ping_packet.icmp_header.ID = ID++;
ping_packet.icmp_header.SeqNumber = SeqNumber++;
ping_packet.dwTime = GetTickCount();
ping_packet.icmp_header.checkSum = ip_checksum((USHORT*)&ping_packet, sizeof(ping_packet));
}
{
static USHORT ID = 1;
static USHORT SeqNumber = 1;
ping_packet.icmp_header.type = ICMP_ECHO;
ping_packet.icmp_header.code = 0;
ping_packet.icmp_header.checkSum = 0;
ping_packet.icmp_header.ID = ID++;
ping_packet.icmp_header.SeqNumber = SeqNumber++;
ping_packet.dwTime = GetTickCount();
ping_packet.icmp_header.checkSum = ip_checksum((USHORT*)&ping_packet, sizeof(ping_packet));
}
int Ping::UnPackPingPacket()
{
return 0;
}
{
return 0;
}
int Ping::SendPacket()
{
PingPacket ping_packet;
PackPingPacket(ping_packet);
int retValue = sendto(sock, // Socket
(const char*)&ping_packet, // Buffer
sizeof(ping_packet),
0, // Flag
(const sockaddr*)&dest, // The Pointer to Socket Address
sizeof(dest)); // Size of Socket Address
if (retValue < 0)
{
cout << "Error in send Packet, error code" << GetLastError() << endl;
return GetLastError();
}
return 0;
}
{
PingPacket ping_packet;
PackPingPacket(ping_packet);
int retValue = sendto(sock, // Socket
(const char*)&ping_packet, // Buffer
sizeof(ping_packet),
0, // Flag
(const sockaddr*)&dest, // The Pointer to Socket Address
sizeof(dest)); // Size of Socket Address
if (retValue < 0)
{
cout << "Error in send Packet, error code" << GetLastError() << endl;
return GetLastError();
}
return 0;
}
int Ping::ReceivePacket()
{
// effetive will be worse?
IPHeader* recv_buf = (IPHeader*)new TCHAR[MAX_DATA_SIZE];
if (recv_buf == NULL)
{
return GetLastError();
}
int fromlen = sizeof(source);
int retValue = recvfrom(sock,
(char*)recv_buf,
MAX_DATA_SIZE,
0,
(sockaddr*)&source,
&fromlen);
if (retValue < 0)
{
cout << "Error in receive packet, error code" << GetLastError() << endl;
return GetLastError();
}
else
{
// Decode ping packet
DecodePingPacket(*recv_buf, retValue);
}
delete []recv_buf;
recv_buf = NULL;
return 0;
}
{
// effetive will be worse?
IPHeader* recv_buf = (IPHeader*)new TCHAR[MAX_DATA_SIZE];
if (recv_buf == NULL)
{
return GetLastError();
}
int fromlen = sizeof(source);
int retValue = recvfrom(sock,
(char*)recv_buf,
MAX_DATA_SIZE,
0,
(sockaddr*)&source,
&fromlen);
if (retValue < 0)
{
cout << "Error in receive packet, error code" << GetLastError() << endl;
return GetLastError();
}
else
{
// Decode ping packet
DecodePingPacket(*recv_buf, retValue);
}
delete []recv_buf;
recv_buf = NULL;
return 0;
}
USHORT ip_checksum(USHORT* buffer, int size)
{
unsigned long cksum = 0;
// Sum all the words together, adding the final byte if size is odd
while (size > 1) {
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size) {
cksum += *(UCHAR*)buffer;
}
// Do a little shuffling
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
// Return the bitwise complement of the resulting mishmash
return (USHORT)(~cksum);
}
{
unsigned long cksum = 0;
// Sum all the words together, adding the final byte if size is odd
while (size > 1) {
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size) {
cksum += *(UCHAR*)buffer;
}
// Do a little shuffling
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
// Return the bitwise complement of the resulting mishmash
return (USHORT)(~cksum);
}
void ReadIPAddress(unsigned long IPAddress)
{
printf("%d.%d.%d.%d/n", UCHAR(IPAddress),
UCHAR(IPAddress >> 8),
UCHAR(IPAddress >> 16),
UCHAR(IPAddress >> 24));
}
{
printf("%d.%d.%d.%d/n", UCHAR(IPAddress),
UCHAR(IPAddress >> 8),
UCHAR(IPAddress >> 16),
UCHAR(IPAddress >> 24));
}
int Ping::DecodePingPacket(const IPHeader& ip_header, const int recvPacketLen)
{
cout << "IPHeader->source_ip:";
ReadIPAddress(ip_header.source_ip);
printf("IPHeader->total_len: %d/r/n", ip_header.total_len);
printf("IPHeader->tos: %d/r/n", ip_header.tos);
printf("IPHeader->ID:%d/r/n", ip_header.ID);
printf("IPheader->ttl:%d/r/n", ip_header.ttl);
USHORT ipheader_len = ip_header.h_len * 4;
if (recvPacketLen < ipheader_len + ICMP_MIN)
{
// Packet is too small
cout << "Receive packet is too small" << endl;
return -1;
}
PingPacket *pingpacket = (PingPacket*)((char*)&ip_header + ipheader_len);
if (pingpacket == NULL)
{
cout << "ICMP Header is NULL" << endl;
return -1;
}
if (pingpacket->icmp_header.type == ICMP_REPLAY)
{
cout << "Reply Packet" << endl;
cout << "time:" << int (GetTickCount() - pingpacket->dwTime) << endl;
}
return 0;
}
{
cout << "IPHeader->source_ip:";
ReadIPAddress(ip_header.source_ip);
printf("IPHeader->total_len: %d/r/n", ip_header.total_len);
printf("IPHeader->tos: %d/r/n", ip_header.tos);
printf("IPHeader->ID:%d/r/n", ip_header.ID);
printf("IPheader->ttl:%d/r/n", ip_header.ttl);
USHORT ipheader_len = ip_header.h_len * 4;
if (recvPacketLen < ipheader_len + ICMP_MIN)
{
// Packet is too small
cout << "Receive packet is too small" << endl;
return -1;
}
PingPacket *pingpacket = (PingPacket*)((char*)&ip_header + ipheader_len);
if (pingpacket == NULL)
{
cout << "ICMP Header is NULL" << endl;
return -1;
}
if (pingpacket->icmp_header.type == ICMP_REPLAY)
{
cout << "Reply Packet" << endl;
cout << "time:" << int (GetTickCount() - pingpacket->dwTime) << endl;
}
return 0;
}
main.cpp
#include "PING.H"
int main()
{
Ping myping;
if (myping.StartClient())
{
cout << "Ping Machine Successfully!" << endl;
}
else
{
cout << "Ping Machine Error!" << endl;
}
return 0;
}
#include "PING.H"
int main()
{
Ping myping;
if (myping.StartClient())
{
cout << "Ping Machine Successfully!" << endl;
}
else
{
cout << "Ping Machine Error!" << endl;
}
return 0;
}