如何实现ping操作?非常着急,请大家指教。 请教大家一个问题,我现在急需要一个类似ping操作的mfc函数,只需要给出ip地址根据返回值就可以判断是否是通的就可以了。谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www.programsalon.com/download.asp?type_id=25 有这样的吗??我知道用Winsock api可以做到,要不你自己包装一下具体你可以参见Windows网络编程 ping操作使用的是ICMP协议,不是TCP/IP协议。 ICMP协议应该是IP协议的一部分,而不是wzt2000(愚人码头)说的不是TCP/IP协议。 我现在的这个程序是console程序,只需要一个函数就可以了,那到vc没有封装好的这样的函数吗?只要简单的返回通和不通就可以了。 ICMP当然不是IP协议的一部分,只不过ICMP打在IP包中发送罢了 to:jennyvenus 非常感谢,请发到,谢谢!你可是帮了我大忙了 如下是我从ping程序中摘录的,其中作了一些修改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 _ihdr { 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;int CNet350::ping(LPSTR lpAddr){ WSADATA wsaData; SOCKET sockRaw; struct sockaddr_in dest,from; struct hostent * hp; int bread,datasize; int fromlen = sizeof(from); int timeout = 1000; char *dest_ip; char *icmp_data; char *recvbuf; unsigned int addr=0; USHORT seq_no = 0; int nRetry; if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){ return SOCKET_INIT_ERROR; } sockRaw = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sockRaw == INVALID_SOCKET) { return SOCKET_CREATE_ERROR; } bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout, sizeof(timeout)); if(bread == SOCKET_ERROR) { closesocket(sockRaw); return SOCKET_SET_ERROR; } timeout = 1000; bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout)); if(bread == SOCKET_ERROR) { closesocket(sockRaw); return SOCKET_SET_ERROR; } memset(&dest,0,sizeof(dest)); hp = gethostbyname(lpAddr); if (!hp){ addr = inet_addr(lpAddr); } if ((!hp) && (addr == INADDR_NONE) ) { closesocket(sockRaw); return CANNOT_REACH_IP; } 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); datasize = DEF_PACKET_SIZE; datasize += sizeof(IcmpHeader); icmp_data = (char*)xmalloc(MAX_PACKET); recvbuf = (char*)xmalloc(MAX_PACKET); if (!icmp_data) { closesocket(sockRaw); return CANNOT_REACH_IP; } memset(icmp_data,0,MAX_PACKET); fill_icmp_data(icmp_data,datasize); for (nRetry = 0; nRetry < 3; nRetry ++) { 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)); bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from, &fromlen); if (bread != SOCKET_ERROR && bwrote != SOCKET_ERROR) break; } closesocket(sockRaw); if (nRetry < 3) return 1; else return CANNOT_REACH_IP;}void CNet350::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));}USHORT CNet350::checksum(USHORT *buffer, int size){ unsigned long cksum=0; while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum);} to: hustwjz,无论怎样我还是先要感谢你的帮助, http://www.starsoftroom.com/downloads/source_code/Ping.zip 呵呵我有的也是Console的不过有Win32的程序,写的不太好,不好意思给你啦 [求助]基于CFormView的SDI程序中如何随窗口变化调整一个静态控件大小? MFC开发? windows入门编程问题 将当前的时间和12点30分30秒比较?在网吧,比较急。 请教!如何让程序发出报警声音~~高手支招~~ 如何获得窗口句柄 这段程序的错误是什么? 一个关于内存泄漏的问提,以下是我的代码 征求:请问各位计算机爱好者如何管理好自己的数据呢? 欢迎跟贴 MFC中如何实现对象指针的传递??? find()函数的写法? 请问Win2000中的net send发消息的命令是调什么API??
我知道用Winsock api可以做到,要不你自己包装一下具体你可以参见Windows网络编程
不是wzt2000(愚人码头)说的
不是TCP/IP协议。
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 _ihdr {
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;int CNet350::ping(LPSTR lpAddr)
{
WSADATA wsaData;
SOCKET sockRaw;
struct sockaddr_in dest,from;
struct hostent * hp;
int bread,datasize;
int fromlen = sizeof(from);
int timeout = 1000;
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no = 0;
int nRetry; if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
return SOCKET_INIT_ERROR;
}
sockRaw = socket (AF_INET,
SOCK_RAW,
IPPROTO_ICMP);
if (sockRaw == INVALID_SOCKET) {
return SOCKET_CREATE_ERROR;
}
bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
closesocket(sockRaw);
return SOCKET_SET_ERROR;
}
timeout = 1000;
bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
closesocket(sockRaw);
return SOCKET_SET_ERROR;
}
memset(&dest,0,sizeof(dest)); hp = gethostbyname(lpAddr); if (!hp){
addr = inet_addr(lpAddr);
}
if ((!hp) && (addr == INADDR_NONE) ) {
closesocket(sockRaw);
return CANNOT_REACH_IP;
} 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); datasize = DEF_PACKET_SIZE;
datasize += sizeof(IcmpHeader); icmp_data = (char*)xmalloc(MAX_PACKET);
recvbuf = (char*)xmalloc(MAX_PACKET); if (!icmp_data) {
closesocket(sockRaw);
return CANNOT_REACH_IP;
}
memset(icmp_data,0,MAX_PACKET);
fill_icmp_data(icmp_data,datasize); for (nRetry = 0; nRetry < 3; nRetry ++) {
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));
bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,
&fromlen);
if (bread != SOCKET_ERROR && bwrote != SOCKET_ERROR)
break;
}
closesocket(sockRaw);
if (nRetry < 3)
return 1;
else
return CANNOT_REACH_IP;
}void CNet350::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));
}USHORT CNet350::checksum(USHORT *buffer, int size)
{
unsigned long cksum=0; while(size >1) {
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size ) {
cksum += *(UCHAR*)buffer;
} cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
我有的也是Console的
不过有Win32的程序,写的不太好,不好意思给你啦