Ping program (C ++ builder + WIN32API)

Source: Internet
Author: User

/// Unit. CPP /////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////

//---------------------------------------------------------------------------

# Include <VCL. h>
# Pragma hdrstop

# Include "unit1.h"
//---------------------------------------------------------------------------
# Pragma package (smart_init)
# Pragma resource "*. DFM"
Tform1 * form1;
//---------------------------------------------------------------------------
_ Fastcall tform1: tform1 (tcomponent * owner)
: Tform (owner)
{

Edit1-> text = "127.0.0.1 ";
Edit2-> text = "64 ";
Edit3-> text = "1000 ";
Memo1-> lines-> clear ();
Seqindex = 0;
Recvpack = 0;
}
//---------------------------------------------------------------------------

Void _ fastcall tform1: button2click (tobject * sender)
{
Close ();
}
//---------------------------------------------------------------------------
Void _ fastcall tform1: button1click (tobject * sender)
{
Inisocket (); // initialization/aftercare
Ping (); // call the Ping function
}
//---------------------------------------------------------------------------
Void tform1: Ping () // The Ping function is completed.
{
Struct hostent * HP;
Char * strhost; // host address
Int ndatasize; // ICMP Packet Length
Int timeout;
Unsigned int ADDR = 0;
Unsigned int dw;

Word wversionrequested;
Wsadata;
Int err;
Wversionrequested = makeword (2, 2 );
Err = wsastartup (wversionrequested, & wsadata );
If (Err! = 0)
{
Memo1-> lines-> Add ("Winsock cannot be created. Check whether the related dynamic link library is missing ");
Return;
}
If (lobyte (wsadata. wversion )! = 2 |
Hibyte (wsadata. wversion )! = 2)
{
Memo1-> lines-> Add ("Winsock cannot be created. Check whether the related dynamic link library is missing ");
Wsacleanup ();
Return;
}

Inisocket ();
// Create a socket object for sending and receiving ICMP messages
If (invalid_socket = (sockraw = socket (af_inet, sock_raw, ipproto_icmp )))
{
Memo1-> lines-> Add ("unable to establish socket object ");
Return;
}
Timeout = edit3-> text. toint (); // you can specify the maximum waiting time.
If (socket_error = setsockopt (sockraw, sol_socket, so_rcvtimeo,
(Char *) & timeout, sizeof (timeout) |
(Socket_error = setsockopt (sockraw, sol_socket, so_sndtimeo,
(Char *) & timeout, sizeof (timeout ))))
{
Memo1-> lines-> Add ("socket error ");
Return;
}

Memset (& sadest, 0, sizeof (sadest); // initialize to 0
// Inet_addr () converts the vertex address to an integer address.
Strhost = edit1-> text. c_str ();
If (inaddr_none = (ADDR = inet_addr (strhost )))
{
// Gethostbyname () DNS domain name address
If (null = (HP = gethostbyname (strhost )))
{
Memo1-> lines-> Add ("Incorrect address ");
Return;
}
Else
{
Sadest. sin_family = hp-> h_addrtype;
Memcpy (& (sadest. sin_addr), HP-> h_addr, HP-> h_length );
}
}
Else
{
Sadest. sin_family = af_inet;
Sadest. sin_addr.s_addr = ADDR;
}
Packetsize = edit2-> text. toint ();
Ndatasize = packetsize + sizeof (icmpheader );
Picmpdata = new char [ndatasize];
Precvbuf = new char [ndatasize + maxipheader];
Memset (picmpdata, 0, ndatasize); // set 0
Fill_icmp_data (picmpdata, ndatasize); // fill in ICMP Packets
Seqindex = 0; // the serial number of this document
Recvpack = 0; // clear the number of received packets
Timer1-> enabled = true; // The timer starts to work.
}

Void tform1: inisocket () // complete initialization/aftercare
{
If (invalid_socket! = Sockraw)
{
Closesocket (sockraw );
Sockraw = invalid_socket;
}
If (null! = Picmpdata)
{
Delete picmpdata;
Picmpdata = NULL;
}
If (null! = Precvbuf)
{
Delete precvbuf;
Precvbuf = NULL;
}
}

Void tform1: fill_icmp_data (char * picmpdata, int ndatasize)
{
Icmpheader * picmphdr;
Char * pdatapart;
Picmphdr = (icmpheader *) picmpdata;
Picmphdr-> I _type = ICMP_Echo;
Picmphdr-> I _code = 0;
Picmphdr-> I _id = (ushort) getcurrentprocessid ();
Picmphdr-> I _seq = 0;
Pdatapart = picmpdata + sizeof (icmpheader );
Memset (pdatapart, 'E', ndatasize-sizeof (icmpheader ));
}
Void _ fastcall tform1: timer1timer (tobject * sender)
{
// Periodically sends ICMP Packets
Int nerror;
Int nwrite, nread;
Sockaddr_in from; // defines the remote socket link address.
Int nfromlen = sizeof (from );
Int ndatasize = packetsize + sizeof (icmpheader );
// If the maximum number of sent packets is exceeded, stop the ping operation.
If (seqindex> = maxnum)
{
Int lost; // message Loss Rate
Lost = (seqindex-recvpack) * 100/seqindex;
Memo1-> lines-> Add ("Lost =" + ansistring (lost) + "% ");
Timer1-> enabled = false;
Inisocket ();
Return;
}
// If the maximum number of sent packets is not exceeded, Ping
(Icmpheader *) picmpdata)-> I _cksum = 0;
(Icmpheader *) picmpdata)-> timestamp = gettickcount (); // Timestamp
(Icmpheader *) picmpdata)-> I _seq = 0 xFFFF & (seqindex ++); // number the message
(Icmpheader *) picmpdata)-> I _cksum = checksum (ushort *) picmpdata,
Ndatasize); // checksum

If (socket_error = (nwrite = sendto (sockraw, picmpdata, ndatasize, 0,
(Struct sockaddr *) & sadest, sizeof (sadest ))))
{
If (wsaetimedout = (nerror = wsagetlasterror ()))
{
Memo1-> lines-> Add ("timeout error ");
}
Else
{
Memo1-> lines-> Add ("message sending error ");
Timer1-> enabled = false; // stop sending packets
}
Return;
}
If (socket_error = (nread = recvfrom (sockraw, precvbuf,
Ndatasize + maxipheader, 0, (struct sockaddr *) & from, & nfromlen )))
{
If (wsaetimedout = (nerror = wsagetlasterror ()))
{
Memo1-> lines-> Add ("timeout error ");
} Else
{
Memo1-> lines-> Add ("receive data error ");
Timer1-> enabled = false; // stop sending packets
}
Return;
}
Decode_resp (precvbuf, nread, & from );
}

Ushort tform1: Checksum (ushort * databuffer, int size) // checksum Function
{
Unsigned long sum = 0;
While (1 <size)
{
Sum + = * databuffer ++;
Size-= sizeof (ushort );
}
If (size)
Sum + = * (uchar *) databuffer;
Sum = (sum> 16) + (sum & 0 xFFFF );
Sum + = (sum> 16 );
Return (ushort )(~ Sum );
}
//---------------------------------------------------------------------------
Bool tform1: decode_resp (char * buffer, int bytes, sockaddr_in * socketfrom)
{// The Program receives an IP message. In order to obtain the ICMP packet, the IP packet must be decomposed.
Ipheader * iphdr;
Icmpheader * icmphdr;
Unsigned short iphdrlen;
Iphdr = (ipheader *) buffer;
Ansistring strofping;
// Iphdrlen is measured in bytes, while the iphdr is measured in 32 bits.
Iphdrlen = iphdr-> h_len <2;
If (iphdrlen + icmp_min)> bytes)
{
Memo1-> lines-> Add ("the number of received bytes is too small ");
Return false;
}
Icmphdr = (icmpheader *) (buffer + iphdrlen );
If (ICMP_ECHOREPLY! = Icmphdr-> I _type)
{
Memo1-> lines-> Add ("type error ");
Return false;
}
If (icmphdr-> I _id! = (Ushort) getcurrentprocessid ())
{
Memo1-> lines-> Add ("not the datagram of this program ");
Return false;
}
++ Recvpack; // The message is correct. Add one to the accumulators.
Strofping = "reply from" + ansistring (inet_ntoa (socketfrom-> sin_addr ))
+ ":" + "Seq" + ansistring (icmphdr-> I _seq)
+ "Bytes =" + ansistring (bytes)
+ "Times =" + ansistring (gettickcount ()-icmphdr-> timestamp) + "Ms"
+ "TTL:" + ansistring (iphdr-> TTL );
Memo1-> lines-> Add (strofping );
Return true;
}
//---------------------------------------------------------------------------

///////////////// //////////////////////////////////////

//---------------------------------------------------------------------------

# Ifndef unit1h
# Define unit1h
//---------------------------------------------------------------------------
# Include <classes. HPP>
# Include <controls. HPP>
# Include <stdctrls. HPP>
# Include <forms. HPP>
# Include <extctrls. HPP>
# Include <winsock2.h>
# Define ICMP_Echo 8
# Define ICMP_ECHOREPLY 0

# Define icmp_min 8 // minimum ICMP header bytes
# Define maxipheader 60 // maximum number of IP datagram bytes
# Define maxnum 10 // defines the number of sent packets
// IP Header

Typedef struct tagipheader {
Unsigned char h_len: 4; // length of the header
Unsigned char version: 4; // version of IP
Unsigned char TOS; // type of service
Unsigned short total_len; // total length of the packet
Unsigned short ident; // Unique Identifier
Unsigned short frag_and_flags; // flags
Unsigned char TTL;
Unsigned char proto; // protocol (TCP, UDP etc)
Unsigned short checksum; // IP checksum

Unsigned int sourceip;
Unsigned int destip;

} Ipheader;
// ICMP Header
Typedef struct tagicmpheader
{
Byte I _type;
Byte I _code;
Ushort I _cksum;
Ushort I _id;
Ushort I _seq;
Ulong timestamp; // Timestamp
} Icmpheader;
//---------------------------------------------------------------------------
Class tform1: Public tform
{
_ Published: // ide-managed Components
Tmemo * memo1;
Tpanel * Panel1;
Tlabel * label1;
Tlabel * label2;
Tlabel * label3;
Tedit * edit1;
Tedit * edit2;
Tedit * edit3;
Tbutton * button1;
Tbutton * button2;
Ttimer * timer1;
Void _ fastcall button2click (tobject * sender );
Void _ fastcall button1click (tobject * sender );
Void _ fastcall timer1timer (tobject * sender );
PRIVATE:

Socket sockraw; // socket object
Char * picmpdata; // point to the ICMP Data Buffer
Char * precvbuf; // point to the receiving data buffer
Sockaddr_in sadest; // the destination address for storing Ping.
Int packetsize; // Data Length
Int seqindex; // the serial number of the message.
Int recvpack; // number of packets received

Void Ping ();
Void inisocket ();
Void fill_icmp_data (char * picmpdata, int ndatasize );
Ushort checksum (ushort * databuffer, int size); // checksum Function
// Data decoding function
Bool decode_resp (char * buffer, int bytes, sockaddr_in * socketfrom );

// User declarations
Public: // user declarations
_ Fastcall tform1 (tcomponent * owner );
};
//---------------------------------------------------------------------------
Extern package tform1 * form1;
//---------------------------------------------------------------------------
# Endif

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.