1.ç¨vbç¼åä¸ä¸ªè°ç¨ping.exeç¨åºã
2.c语言ping程序中文注释
3.ping命令的源码七种用法
ç¨vbç¼åä¸ä¸ªè°ç¨ping.exeç¨åºã
'æ¹è¯äºä¸
'åæ¥4ç§å·ä¸æ¬¡ï¼ç°å¨0.3ç§å·ä¸æ¬¡
'ç°å¨åªè¿å毫ç§äº
'ä½ æ¯ä¸æ¯ä¸ºäºç©å±±å£å±±åï¼
'2个TextBox :
Text1 - è¾å ¥ip
Text2 - æ¾ç¤ºç»æ
'1个Timer : Timer1
'1个CommandButton : Command1
Option Explicit
Private Const NORMAL_PRIORITY_CLASS = &H&
Private Const STARTF_USESTDHANDLES = &H&
Private Const STARTF_USESHOWWINDOW = &H1
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As Long
lpDesktop As Long
lpTitle As Long
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Const FLAG = SWP_NOMOVE Or SWP_NOSIZE
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const HWND_TOP = 0
Const HWND_BOTTOM = 1
Dim Proc As PROCESS_INFORMATION 'è¿ç¨ä¿¡æ¯
Dim Start As STARTUPINFO 'å¯å¨ä¿¡æ¯
Dim SecAttr As SECURITY_ATTRIBUTES 'å®å ¨å±æ§
Dim hReadPipe As Long '读å管éå¥æ
Dim hWritePipe As Long 'åå ¥ç®¡éå¥æ
Dim lngBytesRead As Long '读åºæ°æ®çåèæ°
Dim strBuffer As String * '读å管éçå符串buffer
Dim Command As String 'DOSå½ä»¤
Dim ret As Long 'APIå½æ°è¿åå¼
Private Declare Function SetWindowPos Lib "user" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
ByVal y As Long, ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Declare Function CreatePipe Lib "kernel" (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long
Private Declare Function CreateProcess Lib "kernel" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function ReadFile Lib "kernel" (ByVal hFile As Long, ByVal lpBuffer As String, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CloseHandle Lib "kernel" (ByVal hObject As Long) As Long
Private Sub Command1_Click()
If Not InitPipe Then
Exit Sub
Else
'init
Dim s As String
s = ReadPipe
'Me.Text2.Text = s
Me.Timer1.Enabled = True
End If
End Sub
Private Sub Form_Load()
Call SetWindowPos(Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAG)
Me.Command1.Caption = "Start"
Me.Timer1.Enabled = False
Me.Timer1.Interval =
Me.Text1.Text = "..."
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
ClosePipe
End Sub
Private Sub Timer1_Timer()
Dim strPipe As String
On Error Resume Next
strPipe = ReadPipe()
If Len(strPipe) > 0 Then
If InStr(1, strPipe, "time") > 0 Then
Dim lPosStart As Long
Dim lPosEnd As Long
Dim sMS As String
lPosStart = InStr(strPipe, "time=")
lPosEnd = InStr(strPipe, "ms")
sMS = Mid(strPipe, lPosStart + 5, lPosEnd - lPosStart - 5)
'Text2.Text = Now & "==============>" & vbCrLf & strPipe & vbCrLf & Text2.Text
Text2.Text = sMS & vbCrLf & Text2.Text
End If
End If
End Sub
Private Function InitPipe() As Boolean
'设置å®å ¨å±æ§
With SecAttr
.nLength = LenB(SecAttr)
.bInheritHandle = True
.lpSecurityDescriptor = 0
End With
'å建管é
ret = CreatePipe(hReadPipe, hWritePipe, SecAttr, 0)
If ret = 0 Then
MsgBox "æ æ³å建管é", vbExclamation, "é误"
GoTo ErrHdr
End If
'设置è¿ç¨å¯å¨åçä¿¡æ¯
With Start
.cb = LenB(Start)
.dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
.hStdOutput = hWritePipe '设置è¾åºç®¡é
.hStdError = hWritePipe '设置é误管é
End With
'å¯å¨è¿ç¨
Command = "c:\windows\system\ping.exe -t " & Me.Text1.Text 'DOSè¿ç¨ä»¥ipconfig.exe为ä¾
ret = CreateProcess(vbNullString, Command, SecAttr, SecAttr, True, NORMAL_PRIORITY_CLASS, ByVal 0, vbNullString, Start, Proc)
If ret = 0 Then
MsgBox "æ æ³å¯å¨æ°è¿ç¨", vbExclamation, "é误"
ret = CloseHandle(hWritePipe)
ret = CloseHandle(hReadPipe)
GoTo ErrHdr
End If
If False Then
ErrHdr:
InitPipe = False
Exit Function
End If
InitPipe = True
End Function
Private Function ReadPipe() As String
Dim lpOutputs As String
'å 为æ éåå ¥æ°æ®ï¼æ以å å ³éåå ¥ç®¡éãèä¸è¿éå¿ é¡»å ³éæ¤ç®¡éï¼å¦åå°æ æ³è¯»åæ°æ®
ret = CloseHandle(hWritePipe)
'ä»è¾åºç®¡é读åæ°æ®ï¼æ¯æ¬¡æå¤è¯»ååè
ret = ReadFile(hReadPipe, strBuffer, , lngBytesRead, ByVal 0)
lpOutputs = lpOutputs & Left(strBuffer, lngBytesRead)
ReadPipe = lpOutputs
End Function
Private Sub ClosePipe()
On Error Resume Next
'读åæä½å®æï¼å ³éåå¥æ
ret = CloseHandle(Proc.hProcess)
ret = CloseHandle(Proc.hThread)
ret = CloseHandle(hReadPipe)
End Sub
c语言ping程序中文注释
编写自己的一个ping程序,可以说是许多人迈出网络编程的第一步吧!!这个ping程序的源代码经过我的修改和调试,基本上可以取代windows中自带的ping程序. 各个模块后都有我的详细注释和修改日志,希望能够对大家的学习有所帮助!!
/* 本程序的主要源代码来自MSDN网站, 笔者只是做了一些改进和注释! 另外需要注意的是在Build之前,必须加入ws2_.lib库文件,否则会提示"error LNK:"的错误!*/
Version 1.1 修改记录:
<1> 解决了socket阻塞的源码nettysocketio 源码分析问题,从而能够正确地处理超时的请求!
<2> 增加了由用户控制发送ICMP包的数目的功能(即命令的第二个参数)
<3> 增加了对ping结果的统计功能.
#pragma pack(4)
#include "winsock2.h"
#include "stdlib.h"
#include "stdio.h"
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)
/* The IP header */
typedef struct iphdr {
unsigned int h_len:4; // length of the header
unsigned int 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 icmphdr {
BYTE i_type;
BYTE i_code; /* type sub code */
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
/* This is not the std header, but we reserve space for time */
ULONG timestamp;
}IcmpHeader;
#define STATUS_FAILED 0xFFFF
#define DEF_PACKET_SIZE
#define DEF_PACKET_NUMBER 4 /* 发送数据报的个数 */
#define MAX_PACKET
#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define xfree(p) HeapFree (GetProcessHeap(),0,(p))
void fill_icmp_data(char *, int);
USHORT checksum(USHORT *, int);
int decode_resp(char *,int ,struct sockaddr_in *);
void Usage(char *progname){
fprintf(stderr,"Usage:\n");
fprintf(stderr,"%s [number of packets] [data_size]\n",progname);
fprintf(stderr,"datasize can be up to 1Kb\n");
ExitProcess(STATUS_FAILED);
}
int main(int argc, char **argv){
WSADATA wsaData;
SOCKET sockRaw;
struct sockaddr_in dest,from;
struct hostent * hp;
int bread,datasize,times;
int fromlen = sizeof(from);
int timeout = ;
int statistic = 0; /* 用于统计结果 */
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no = 0;
if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
fprintf(stderr,"WSAStartup failed: %d\n",GetLastError());
ExitProcess(STATUS_FAILED);
}
if (argc <2 ) {
Usage(argv[0]);
}
sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL, 0,WSA_FLAG_OVERLAPPED);
//
//注:为了使用发送接收超时设置(即设置SO_RCVTIMEO, SO_SNDTIMEO),
// 必须将标志位设为WSA_FLAG_OVERLAPPED !
//
if (sockRaw == INVALID_SOCKET) {
fprintf(stderr,源码liunx源码断点"WSASocket() failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
timeout = ;
bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
memset(&dest,0,sizeof(dest));
hp = gethostbyname(argv[1]);
if (!hp){
addr = inet_addr(argv[1]);
}
if ((!hp) && (addr == INADDR_NONE) ) {
fprintf(stderr,"Unable to resolve %s\n",argv[1]);
ExitProcess(STATUS_FAILED);
}
if (hp != NULL)
memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
else
dest.sin_addr.s_addr = addr;
if (hp)
dest.sin_family = hp->h_addrtype;
else
dest.sin_family = AF_INET;
dest_ip = inet_ntoa(dest.sin_addr);
//
// atoi函数原型是: int atoi( const char *string );
// The return value is 0 if the input cannot be converted to an integer !
//
if(argc>2)
{
times=atoi(argv[2]);
if(times == 0)
times=DEF_PACKET_NUMBER;
}
else
times=DEF_PACKET_NUMBER;
if (argc >3)
{
datasize = atoi(argv[3]);
if (datasize == 0)
datasize = DEF_PACKET_SIZE;
if (datasize >) /* 用户给出的数据包大小太大 */
{
fprintf(stderr,"WARNING : data_size is too large !\n");
datasize = DEF_PACKET_SIZE;
}
}
else
datasize = DEF_PACKET_SIZE;
datasize += sizeof(IcmpHeader);
icmp_data = (char*)xmalloc(MAX_PACKET);
recvbuf = (char*)xmalloc(MAX_PACKET);
if (!icmp_data) {
fprintf(stderr,"HeapAlloc failed %d\n",GetLastError());
ExitProcess(STATUS_FAILED);
}
memset(icmp_data,0,MAX_PACKET);
fill_icmp_data(icmp_data,datasize);
//
//显示提示信息
//
fprintf(stdout,"\nPinging %s ....\n\n",dest_ip);
for(int i=0;i{
int bwrote;
((IcmpHeader*)icmp_data)->i_cksum = 0;
((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
((IcmpHeader*)icmp_data)->i_seq = seq_no++;
((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data,datasize);
bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest));
if (bwrote == SOCKET_ERROR){
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("Request timed out.\n");
continue;
}
fprintf(stderr,"sendto failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
if (bwrote < datasize ) {
fprintf(stdout,"Wrote %d bytes\n",bwrote);
}
bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,&fromlen);
if (bread == SOCKET_ERROR){
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("Request timed out.\n");
continue;
}
fprintf(stderr,"recvfrom failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
if(!decode_resp(recvbuf,bread,&from))
statistic++; /* 成功接收的数目++ */
Sleep();
}
/
*Display the statistic result
*/
fprintf(stdout,"\nPing statistics for %s \n",dest_ip);
fprintf(stdout," Packets: Sent = %d,Received = %d, Lost = %d (%2.0f%% loss)\n",times,
statistic,(times-statistic),(float)(times-statistic)/times*);
WSACleanup();
return 0;
}
/*
The response is an IP packet. We must decode the IP header to locate
the ICMP data
*/
int decode_resp(char *buf, int bytes,struct sockaddr_in *from) {
IpHeader *iphdr;
IcmpHeader *icmphdr;
unsigned short iphdrlen;
iphdr = (IpHeader *)buf;
iphdrlen = (iphdr->h_len) * 4 ; // number of -bit words *4 = bytes
if (bytes < iphdrlen + ICMP_MIN) {
printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));
}
icmphdr = (IcmpHeader*)(buf + iphdrlen);
if (icmphdr->i_type != ICMP_ECHOREPLY) {
fprintf(stderr,"non-echo type %d recvd\n",icmphdr->i_type);
return 1;
}
if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) {
fprintf(stderr,"someone else''s packet!\n");
return 1;
}
printf("%d bytes from %s:",bytes, inet_ntoa(from->sin_addr));
printf(" icmp_seq = %d. ",icmphdr->i_seq);
printf(" time: %d ms ",GetTickCount()-icmphdr->timestamp);
printf("\n");
return 0;
}
USHORT checksum(USHORT *buffer, int size) {
unsigned long cksum=0;
while(size >1) {
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size) {
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> ) + (cksum & 0xffff);
cksum += (cksum >>);
return (USHORT)(~cksum);
}
/*
Helper function to fill in various stuff in our ICMP request.
*/
void fill_icmp_data(char * icmp_data, int datasize){
IcmpHeader *icmp_hdr;
char *datapart;
icmp_hdr = (IcmpHeader*)icmp_data;
icmp_hdr->i_type = ICMP_ECHO;
icmp_hdr->i_code = 0;
icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
icmp_hdr->i_cksum = 0;
icmp_hdr->i_seq = 0;
datapart = icmp_data + sizeof(IcmpHeader);
//
// Place some junk in the buffer.
//
memset(datapart,''E'', datasize - sizeof(IcmpHeader));
}
/