如何在程序中测试网站是否访问成功(ping)

zhoumingyang 2004-01-27 08:04:08
我在程序中加入了访问网站的功能,但是在程序运行时,有时候提示不能访问目标网页,在Windows的命令行方式中,可以使用ping命令来检测目标网站是否通畅,我想问的是,如何在程序中判断目标网站能否接通,也就是实现PING命令的功能?
...全文
168 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
哟西哟西地 2004-01-27
  • 打赏
  • 举报
回复
刚写的个PING程序源码:

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct tagIP_HEADER{
unsigned int h_len:4; //length of header (4b)
unsigned int ver:4; //version (4b)
unsigned char tos; //tos (1B)
unsigned short total_len; //total length (2B)
unsigned short ident; //identification (2B)
unsigned short frag_flags; //frag and flags (2B)
unsigned char ttl; //time of lives (1B)
unsigned char protocol; //protocol (1B)
unsigned short checksum; //checksum (2B)
unsigned int sourceip; //source ip (4B)
unsigned int destip; //destination ip (4B)
}IP_HEADER,*PIP_HEADER; //length of total (20B)

typedef struct tagIP_OPT_HEADER{
unsigned char code; //option type (1B)
unsigned char len; //length of option header (1B)
unsigned char ptr; //下一个可存放地址的位置 (1B)
unsigned long addr[9]; //list of ip address (4B/d)
}IP_OPT_HEADER,*PIP_OPT_HEADER; //length of total (39B)

typedef struct tagICMP_HEADER{
unsigned char type; //icmp type (1B)
unsigned char code; //code of type (1B)
unsigned short checksum; //checksum (2B)
unsigned short id; //identification (2B)
unsigned short seq; //sequence (2B)
unsigned long timestamp; // (2B)
//this is not standard header,but we reserve space for time
}ICMP_HEADER,*PICMP_HEADER; //total length (10B)

#define DEF_PACKET_SIZE 32
#define MAX_PACKET_SIZE 1024
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define IP_RECORD_ROUTER 7

void usageinfo(char *progname);
void FillIcmpData(char *icmp_data,int size);
USHORT CheckSum(USHORT *buf,int size);
void DecodeIcmpHeader(char *buf,int ret,LPSOCKADDR_IN lpSin);
void DecodeIpHeader(char *buf,int bytes);

。CPP


#include "Ping.h"


int main(int argc,char *argv[])
{ //error:return -1,no err:return 0
if(argc==1)
{
usageinfo(argv[0]);
return -1;
}

BOOL bRecordRout =FALSE;
SOCKET hSocket =INVALID_SOCKET;
SOCKADDR_IN dstSin;
SOCKADDR_IN fromSin;
IP_OPT_HEADER ipOptHeader;
char* pIcmpData =NULL;
char* pRecvData =NULL;
char* lpDstIp =NULL;
int datasize =DEF_PACKET_SIZE;
int ret;

for(int i=1;i<argc;i++)
{
if(strchr(argv[i],'-')){
switch(tolower(argv[i][1])){
case 'r':
bRecordRout=TRUE;
break;
case 'd':
datasize=atoi(argv[i+1]);
i=argc+1; // to quit the for loop
break;
}
}
else if(strchr(argv[i],'.')){
int l=strlen(argv[i]);
if(l<7||l>15)
usageinfo(argv[0]);
else
lpDstIp=argv[i];
}
}

//initialize winsock
//
WSADATA wsaData;
WORD wVer=MAKEWORD(2,2);
if(WSAStartup(wVer,&wsaData)!=0){
printf("WSAStartup Error!\n");
return -1; //err,return -1,
}
//create socket handle
//
hSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);
if(hSocket==INVALID_SOCKET)
{
printf("WSASocket Error,Code:%d",WSAGetLastError());
WSACleanup();
return -1;
}

//set ip option header(record router)
if(bRecordRout)
{
ZeroMemory(&ipOptHeader,sizeof(ipOptHeader));
ipOptHeader.code=IP_RECORD_ROUTER;
ipOptHeader.len=39;
ipOptHeader.ptr=4;
if((ret=setsockopt(hSocket,IPPROTO_IP,IP_OPTIONS,(char *)&ipOptHeader,
sizeof(ipOptHeader)))==SOCKET_ERROR){
printf("setsockopt(IP_OPTIONS) error,code:%d",WSAGetLastError());
WSACleanup();
closesocket(hSocket);
return -1;
}
}

//set socket recv and send timeout;
int timeout=1000;
if((ret=setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)))==SOCKET_ERROR)
{
printf("setsockopt(SO_RCVTIMEO) error,code:%d",WSAGetLastError());
WSACleanup();
closesocket(hSocket);
return -1;
}
if((ret=setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)))==SOCKET_ERROR){
printf("setsockopt(SO_SNDTIMEO) error,code:%d",WSAGetLastError());
WSACleanup();
return -1;
}

pIcmpData=(char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET_SIZE);
pRecvData=(char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET_SIZE);
if(pIcmpData==NULL||pRecvData==NULL)
{
printf("HeapAlloc Error\n");
WSACleanup();
return -1;
}
datasize+=sizeof(ICMP_HEADER);
ZeroMemory(&dstSin,sizeof(dstSin));
dstSin.sin_family=AF_INET;
dstSin.sin_addr.s_addr=inet_addr(lpDstIp);
FillIcmpData(pIcmpData,datasize);
printf("Ping %s with %d bytes of data\n",inet_ntoa(dstSin.sin_addr),datasize);
int count=0;
int seq=0;
int rcvNum=0;
while(1)
{
count++;
if(count==5)
break;
((PICMP_HEADER)pIcmpData)->checksum=0;
((PICMP_HEADER)pIcmpData)->seq=seq++;
((PICMP_HEADER)pIcmpData)->timestamp=GetTickCount();
((PICMP_HEADER)pIcmpData)->checksum=
CheckSum((USHORT*)pIcmpData,datasize);
if((ret=sendto(hSocket,pIcmpData,datasize,0,(LPSOCKADDR)&dstSin,sizeof(dstSin)))==SOCKET_ERROR){
if(WSAGetLastError()==WSAETIMEDOUT){
printf("time out.\n");
continue;
}
else{
printf("sendto error,code:%d",WSAGetLastError());
closesocket(hSocket);
WSACleanup();
return -1;
}
}
int fromLen=sizeof(fromSin);
if((ret=recvfrom(hSocket,pRecvData,MAX_PACKET_SIZE,0,(sockaddr *)&fromSin,
&fromLen))==SOCKET_ERROR){
if(WSAGetLastError()==WSAETIMEDOUT)
{
printf("time out.\n");
continue;
}
printf("recvform fail!\n");
closesocket(hSocket);
WSACleanup();
return -1;
}
rcvNum++;
DecodeIcmpHeader(pRecvData,ret,&fromSin);
}

printf("\n Ping Statistics for : %s\n",lpDstIp);
printf("\t Send= %d, Received= %d,Lost= %d (%d%% loss)",4,rcvNum,4-rcvNum,(4-rcvNum)/4*100);

if(hSocket!=INVALID_SOCKET)
closesocket(hSocket);

HeapFree(GetProcessHeap(),0,pIcmpData);
HeapFree(GetProcessHeap(),0,pRecvData);
WSACleanup();

return 0;
}

void usageinfo(char *progname)
{
printf("Ping tool,by blode(blode@peoplemail.com.cn\n");
printf("usage:ping [-r] <host ip> [-d ][data size]\n");
printf("\t-r:\trecord router\n");
printf("\thost ip:\thost ip to ping\n");
printf("\t-d:\tuse data size option\n");
printf("\tdata size:\tdata size to ping(<=1024)\n");
}

void FillIcmpData(char *icmp_data,int size)
{
ICMP_HEADER *icmpHdr;
icmpHdr=(PICMP_HEADER)icmp_data;
icmpHdr->checksum=0;
icmpHdr->code=0;
icmpHdr->id=(unsigned short)GetCurrentProcessId();
icmpHdr->seq=0;
icmpHdr->type=ICMP_ECHO;
icmpHdr->timestamp=0;
}

USHORT CheckSum(USHORT *buf,int size)
{ //check sum function
USHORT cksum=0;
while(size>1)
{
cksum+=*buf++;
size-=sizeof(USHORT);
}
if(size)
cksum+=*buf++;
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return (USHORT)(~cksum);
}

void DecodeIcmpHeader(char *buf,int ret,LPSOCKADDR_IN lpSin)
{
ICMP_HEADER *icmpHdr;
IP_HEADER *ipHdr;
int ipHdrLen;
static int first=0;
DWORD tick=GetTickCount();
ipHdr=(IP_HEADER*)buf;
ipHdrLen=ipHdr->h_len*4;
if(ipHdrLen==60&&!first)
DecodeIpHeader(buf,ret);

icmpHdr=(ICMP_HEADER *)(buf+ipHdrLen);
if(icmpHdr->type!=ICMP_ECHOREPLY){
printf("no echo reply %d recved\n",icmpHdr->type);
return;
}
if(icmpHdr->id!=(USHORT)GetCurrentProcessId()){
printf("someone else's packet!\n");
return;
}
printf("Reply from: %s",inet_ntoa(lpSin->sin_addr));
printf("\tbytes: %d icmp seq: %d TTL=128",ret,icmpHdr->seq);
printf(" time: %dms\n",tick-icmpHdr->timestamp);
first++;

return;
}

void DecodeIpHeader(char *buf,int bytes)
{
IP_OPT_HEADER *ipOptHdr;
IN_ADDR in;

ipOptHdr=(IP_OPT_HEADER*)(buf+20);
printf("Record Router: ");
for(int i=0;i<(ipOptHdr->ptr/4)-1;i++){
in.S_un.S_addr=ipOptHdr->addr[i];
printf("\t%-15s\n",inet_ntoa(in));
}
}
zhangcrony 2004-01-27
  • 打赏
  • 举报
回复
支持,UP一下!
tohigh 2004-01-27
  • 打赏
  • 举报
回复
有些网站不能ping通
最近好像电信网关把ICMP包给过滤掉了。
用GetHttpConnection或者OpenURL的返回值就可以判断。
用wininet下载网页的流程:
1 open
2 connect
3 openrequest
4 sendrequest
5 queryinfo
6 readfile

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧