谢谢.
解决方案 »
- vs2010调试的全局强制中断快捷键是啥?
- 多套接字问题请教?
- WIN SERVER 2003 下如何向别的进程注入DLL
- 关于接口、实现、与类的一个问题
- 怎么让别人的程序上的按钮消失??
- 这可怎么办呢?高手快来指点,估计快要下岗了!
- 我想参加开发团队,先做一个业余程序员,做出一点实用的软件,不知有没有开发团队会接收我?
- 我会将单个位图加入菜单,就是一对一加进去,但是怎样将一个位图不同部分加入到不同的菜单中去,就像网络蚂蚁那样
- 用VC如何合并Word文件
- 谁到http://www.skinsharp.com/这个网址上买过Skinsharp界面库,联系不到人啊
- 图片尺寸采用十进制和二进制在性能上差别有多大?
- 请问这里的undeclared identifier该怎么解决呢?
#ifndef __NET_ICMP_H__
#define __NET_ICMP_H__#include <winsock2.h>
///////////////////////////////////////////////////////////////////////////
// icmp struct
typedef struct IP
{
unsigned char ip_ver : 4; /* 4位版本 */
unsigned char ip_hlen : 4; /* 4位长度 */
unsigned char ip_tos; /* 8位服务类型 */
unsigned short ip_len;
unsigned short ip_id;
unsigned short ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short ip_sum;
unsigned long ip_src;
unsigned long ip_dst;
} IP;typedef struct ICMP
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_cksum;
unsigned short icmp_id;
unsigned short icmp_seq;
unsigned long icmp_data;
} ICMP;#define SEND_BUFFER_LEN 1024
#define SEND_SIZE 32
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0///////////////////////////////////////////////////////////////////////////////
// class CNetIcmp define
class CNetIcmp
{
public:
virtual int InitSocket(const char *lpDestHost="127.0.0.1", int nTimeout=1000);
virtual int Ping(); CNetIcmp();
virtual ~CNetIcmp();private:
int SetIcmpData();private:
void ParseRecvMessage(const char* lpData, int len);
unsigned short CheckSum(unsigned short* lpData, int nLen);
SOCKET m_sockfd;
struct sockaddr_in m_addr_in;
struct sockaddr_in m_from_addr_in; int m_pid; char m_szbuffer[SEND_BUFFER_LEN];
};#endif实现文件:
#include <NETICMP.H>
#include <process.h>
#include <stdio.h>CNetIcmp::CNetIcmp()
{
m_pid = getpid();
}CNetIcmp::~CNetIcmp()
{
}int CNetIcmp::Ping()
{
int nLen = SetIcmpData();
if ((sendto(m_sockfd, (char*)m_szbuffer, nLen, 0, (struct sockaddr*)&m_addr_in, sizeof(m_addr_in))) < 0)
{
printf("目标主机不可到达。\n");
return WSAGetLastError();
} char szRecvBuffer[SEND_BUFFER_LEN];
::memset(szRecvBuffer, 0, sizeof(szRecvBuffer)); memset((char*)&m_from_addr_in, 0, sizeof(m_from_addr_in));
int nAddrLen = sizeof(m_from_addr_in);
int nRecvLen = 0;
if (0 > (nRecvLen = recvfrom(m_sockfd, (char*)szRecvBuffer, sizeof(szRecvBuffer), 0, (struct sockaddr*)&m_from_addr_in, &nAddrLen)))
{
::printf("应答超时!\n");
return WSAGetLastError();
} ParseRecvMessage(szRecvBuffer, nRecvLen); return 0;
}int CNetIcmp::InitSocket(const char *lpDestHost, int nTimeout)
{
WSADATA wsaData;
WORD wVersionRequested;
struct protoent* ppe; wVersionRequested = MAKEWORD(2, 0); if (::WSAStartup(wVersionRequested, &wsaData))
{
return 0 - WSAGetLastError();
}
if (!(ppe = getprotobyname("icmp")))
{
return 0 - WSAGetLastError();
} if (SOCKET_ERROR == (m_sockfd = socket(AF_INET, SOCK_RAW, ppe->p_proto)))
{
return 0 - WSAGetLastError();
} if (SOCKET_ERROR == setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeout, sizeof(nTimeout)))
{
return 0 - WSAGetLastError();
} if (SOCKET_ERROR == setsockopt(m_sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeout, sizeof(nTimeout)))
{
return 0 - WSAGetLastError();
} m_addr_in.sin_family = AF_INET;
m_addr_in.sin_addr.s_addr = inet_addr(lpDestHost); return 0;
}int CNetIcmp::SetIcmpData()
{
int npackagesize = SEND_SIZE + 8; ICMP* picmp = NULL;
memset(m_szbuffer, 0, sizeof(m_szbuffer));
picmp = (ICMP*)m_szbuffer; picmp->icmp_type = ICMP_ECHO;
picmp->icmp_code = 0;
picmp->icmp_seq = 0;
picmp->icmp_id = m_pid;
picmp->icmp_data = GetTickCount();
picmp->icmp_cksum = CheckSum((unsigned short*)picmp, npackagesize); return npackagesize;
}unsigned short CNetIcmp::CheckSum(unsigned short *lpData, int nLen)
{
int nLeft = nLen;
unsigned long sum = 0;
unsigned short *w = lpData;
unsigned short answer = 0; while(nLeft > 1)
{
sum += *w++;
nLeft -= 2;
} if(nLeft == 1)
{
*(unsigned char*)(&answer) = *(unsigned char*)w;
sum += answer;
} sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return answer;
}void CNetIcmp::ParseRecvMessage(const char *lpData, int len)
{
IP* ip;
ICMP* icmp;
double rtt;
int iphdrlen; ip=(IP*)lpData; iphdrlen = ip->ip_hlen * 4;
icmp=(ICMP*)(lpData + iphdrlen);
//if( (icmp->icmp_type == ICMP_ECHOREPLY) && (icmp->icmp_id == m_pid) )
if( 1 )
{
len = len - iphdrlen - 8;
rtt = GetTickCount() - icmp->icmp_data; printf("Reply from %s: bytes=%d time=%.0fms TTL=%d icmp_seq=%u\n",
inet_ntoa(m_from_addr_in.sin_addr),
len,
rtt,
ip->ip_ttl,
icmp->icmp_seq);
return;
}
return ;
}