参考链接:

http://blog.csdn.net/zpxili/article/details/11542041

http://blog.csdn.net/cbuttonst/article/details/7610801

上面两位兄弟的是发一个icmp包,就收一次。在我的电脑上运行的时候,

估计是我的网络中有回环,结果每次收到的都是刚刚发出去的icmp包,

用wireshark抓包又能够抓到正确的reply包。调试了好久,修改如下。

//CPing.h

#ifndef CPING_HJ
#define CPING_HJ
#include <WinSock2.h>
#include <string>
typedef struct _SICMPHDR //icmp
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;
unsigned short icmp_id;
unsigned short icmp_sequence;
unsigned long icmp_timestamp;
} ICMPHDR, *PICMPHDR;
typedef struct _SIPHDR //ip
{
UCHAR ip_hVerLen;
UCHAR ip_TOS;
USHORT ip_Length;
USHORT ip_ID;
USHORT ip_Flags;
UCHAR ip_TTL;
UCHAR ip_Protacol;
USHORT ip_Checksum;
ULONG ip_Source;
ULONG ip_Destination;
} IPHDR;
class CPing
{
public:
CPing();
~CPing();
void m_vPing();
private:
bool m_bSendData(char* pcBuf,int nBufLen,sockaddr_in* pstAddr);
bool m_bRecvData(char* pcBuf,int iBufLen,sockaddr_in* pstRecvAddr,int &riRecvLen);
void m_vInitICMP(PICMPHDR pstICMPHDR,int nSequence);
u_short m_usCheckSum(unsigned short *pusBuf,int iLen);
SOCKET m_iSocket;
};
#endif

//CPing.cpp

#include "CPing.h"
#include <stdio.h>
#define DATA_SIZE 32
#define RECV_SIZE 1024
const int SEND_PACKAGE_SIZE = 30;
const int MAX_TIME = 3000; //ms
CPing::CPing()
{
WSADATA wsaData;
WORD wVersion;
wVersion = MAKEWORD(2,2);
int nRet = WSAStartup(wVersion,&wsaData);
if( nRet != 0 )
{
printf("WSAStartup failed with error: %d\n", nRet);
return;
}
if( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 )
{
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return;
}
m_iSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if( m_iSocket == INVALID_SOCKET )
{
printf("Socket err\n");
WSACleanup();
return;
}
}
CPing::~CPing()
{
if( INVALID_SOCKET != m_iSocket )
{
closesocket(m_iSocket);
}
WSACleanup();
}
void
CPing::m_vPing()
{
char acName[] = "www.vidagrid.com";
hostent *pstHost = gethostbyname(acName);
if( pstHost == NULL )
{
printf("CPing::m_vPing() gethostbyname err\n");
return;
}
sockaddr_in stDesAddr;
stDesAddr.sin_family = AF_INET;
stDesAddr.sin_port = htons(0);
stDesAddr.sin_addr = *((struct in_addr *)(pstHost->h_addr));
//stDesAddr.sin_addr.s_addr = inet_addr("172.17.92.110");
char acIPAddr[23] = {0};
strcpy(acIPAddr, inet_ntoa(stDesAddr.sin_addr));
printf("CPing::m_vPing() acIPAddr: %s\n", acIPAddr);
int iSendBufLen = sizeof(ICMPHDR) + DATA_SIZE;
char* pcIcmp = new char[iSendBufLen];
memset(pcIcmp, 0, iSendBufLen);
PICMPHDR pstIcmp = (PICMPHDR)pcIcmp;
int iSequence = 0;
int iCount = SEND_PACKAGE_SIZE;
while ( iCount-- > 0 )
{
m_vInitICMP(pstIcmp, iSequence++);
pstIcmp->icmp_checksum = m_usCheckSum((unsigned short*)pstIcmp,sizeof(ICMPHDR) + DATA_SIZE); //校验值
m_bSendData((char*)pstIcmp, iSendBufLen, &stDesAddr);
}
int iMinimum = 0;
int iMaximum = 0;
int iSumTime = 0;
iCount = 0;
DWORD dwStartTime = GetTickCount();
printf("\nPinging %s [%s] with 32 bytes of data:\n\n", acName, acIPAddr);
while( (GetTickCount()-dwStartTime) <= MAX_TIME)
{
sockaddr_in stRcvAddr;
char acBuf[RECV_SIZE] = {0};
int iRecvLen = 0;
m_bRecvData(acBuf, sizeof(acBuf), &stRcvAddr, iRecvLen);
int iHeadLen = sizeof(IPHDR) + sizeof(ICMPHDR) + DATA_SIZE;
if( iRecvLen < iHeadLen )
{
printf("CPing::m_vPing() tool few data~\n\n");
continue;
}
IPHDR *ipHead = (IPHDR *)acBuf;
PICMPHDR icmpRecv = (PICMPHDR) (acBuf + sizeof(IPHDR) );
if( icmpRecv->icmp_type != 0 )
{
printf("CPing::m_vPing() Icmp Type err~, 0x%x\n\n", icmpRecv->icmp_type);
continue;
}
if( icmpRecv->icmp_id != GetCurrentProcessId() )
{
printf("CPing::m_vPing() Icmp ID err~\n\n");
continue;
}
int iCurUsedTime = GetTickCount() - icmpRecv->icmp_timestamp;
printf("Reply from %s: bytes=%d time=%ums TTL=%d\n",
inet_ntoa(stRcvAddr.sin_addr),
DATA_SIZE,
iCurUsedTime,
ipHead->ip_TTL);
iSumTime += iCurUsedTime;
if(iCount != 0)
{
if(iCurUsedTime<iMinimum) iMinimum = iCurUsedTime;
else if(iCurUsedTime>iMaximum) iMaximum = iCurUsedTime;
}
else
{
iMinimum = iCurUsedTime;
iMaximum = iCurUsedTime;
}
iCount++;
}
//show statistics
printf("\nPing statistics for %s:\n", acIPAddr);
printf("\tPackets: Sent = %d, Received = %d, Lost = %d (%.2lf%% loss),\n",
SEND_PACKAGE_SIZE, iCount, SEND_PACKAGE_SIZE-iCount, ((double)(SEND_PACKAGE_SIZE-iCount))/SEND_PACKAGE_SIZE*100 );
printf("Approximate round trip times in milli-seconds:\n");
printf("\tMinimum = %dms, Maximum = %dms, Average = %dms\n",
iMinimum, iMaximum, iSumTime/iCount);
delete pcIcmp;
getchar();
}
bool
CPing::m_bSendData(char* pcBuf,int iBufLen,sockaddr_in* pstAddr)
{
printf("CPing::m_bSendData() \n");
if( pstAddr == NULL )
{
printf("CPing::m_bSendData() pstAddr == NULL\n");
return false;
}
int iTimeout = 1000;
int iRet = setsockopt(m_iSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&iTimeout, sizeof(int));
if( iRet == SOCKET_ERROR )
{
printf("CPing::m_bSendData() setsockopt SO_SNDTIMEO err\n");
return false;
}
iRet = sendto(m_iSocket, pcBuf, iBufLen, 0, (sockaddr*)pstAddr, sizeof(sockaddr));
if( iRet == SOCKET_ERROR )
{
if (WSAETIMEDOUT == WSAGetLastError())
{
printf("CPing::m_bSendData() timeout err\n");
return false;
}
else
{
printf("CPing::m_bSendData() sendto err\n");
return false;
}
}
return true;
}
bool
CPing::m_bRecvData(char* pcBuf,int iBufLen,sockaddr_in* pstRecvAddr,int &riRecvLen)
{
printf("CPing::m_bRecvData() \n");
if( INVALID_SOCKET == m_iSocket )
{
printf("CPing::m_bRecvData() INVALID_SOCKET\n");
return false;
}
int iTimeout = 1000;
int iRet = setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO , (char*)&iTimeout, sizeof(int));
if( SOCKET_ERROR == iRet )
{
printf("CPing::m_bRecvData() setsockopt SO_RCVTIMEO error\n");
return false;
}
int nAddrLen = sizeof(sockaddr);
iRet = recvfrom(m_iSocket, pcBuf, iBufLen, 0, (sockaddr*)pstRecvAddr, &nAddrLen);
if( SOCKET_ERROR == iRet )
{
if (WSAETIMEDOUT == WSAGetLastError())
{
printf("CPing::m_bRecvData() timeout err\n");
return false;
}
else
{
printf("CPing::m_bRecvData() recvfrom err\n");
return false;
}
}
riRecvLen = iRet;
return true;
}
void
CPing::m_vInitICMP(PICMPHDR pstICMPHDR,int iSequence)
{
if( pstICMPHDR == NULL )
return;
pstICMPHDR->icmp_type = 8; //request
pstICMPHDR->icmp_code = 0; //icmp request
pstICMPHDR->icmp_sequence = iSequence;
pstICMPHDR->icmp_id = (unsigned short)GetCurrentProcessId();
pstICMPHDR->icmp_timestamp = GetTickCount();
pstICMPHDR->icmp_checksum = 0; //校验值
}
unsigned short
CPing::m_usCheckSum(unsigned short *pusBuf,int iLen)
{
USHORT cksum=0;
while(iLen>1)
{
cksum+=*pusBuf++;
iLen-=sizeof(USHORT);
}
if(iLen)
{
cksum+=*pusBuf++;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return (USHORT)(~cksum);
}

//main.cpp

#include "CPing.h"
#include <stdio.h>
#include <winsock2.h>
#include <iostream>
#include <windows.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main()
{
CPing oPing;
oPing.m_vPing();
return 0;
}

当icmp_type8时,这是一个请求包(ECHO包)。

当icmp_type0时,这是一个响应消息报(ECHO REPLY包),就是对请求包的回应。

socket 发送Ping包的更多相关文章

  1. python socket发送魔法包网络唤醒开机.py

    python socket发送魔法包网络唤醒开机.py 现在的电脑应该都普遍支持有线网络的WOL了,支持无线网络唤醒的电脑,可能比较少. """ python socke ...

  2. 【网络编程2】网络编程基础-发送ICMP包(Ping程序)

    IP协议 网络地址和主机协议 位于网络层的协议,主要目的是使得网络能够互相通信,该协议使用逻辑地址跨网络通信,目前有两个版本IPV4,IPV6. 在IPV4协议中IP地址是一个32位的数备,采用点分四 ...

  3. C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全

    简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...

  4. c++如何使用SOCKET 发送HTTP1.1 GET POST请求包

    如何使用SOCKET 发送HTTP1.1 GET POST请求包 分类: 无线通信 C/C++2009-10-29 10:58 14259人阅读 评论(15) 收藏 举报 socket服务器actio ...

  5. loadrunner使用socket协议来实现客户端对服务器产生压力实例。(通过发送心跳包,达到连接多个客户端的目的)

    #include "lrs.h" vuser_init(){ char *ip; int handler; //编写获取LR分配的Vuser IP函数,将IP保存在ip变量中. i ...

  6. python网络编程-socket发送大数据包问题

    一:什么是socket大数据包发送问题 socket服务器端或者客户端在向对方发送的数据大于对方接受的缓存时,会出现第二次接受还接到上次命令发送的结果.这就出现象第一次接受结果不全,第二次接果出现第一 ...

  7. sendto频率过快导致发送丢包

    编写一个转发模块,虽然没有要求一转多时要达到多少路(不采用组播的情况下,单纯的一路转成多路),但是本着物尽其用的原则,尽可能测试一下极限. 网络环境:1000M,直连,多网卡 系统:Linux ver ...

  8. android firmware 利用UDP socket发送Magic Packet--c语言版本

    android firmware 利用UDP socket发送Magic Packet 1 Magic Packet格式: 6个0xFF + 16个Dst Mac Address 2 代码需要设置目的 ...

  9. socket的半包,粘包与分包的问题

    http://zhaohuiopensource.iteye.com/blog/1541270 首先看两个概念: 短连接: 连接->传输数据->关闭连接    HTTP是无状态的,浏览器和 ...

随机推荐

  1. Heritrix源码分析(十四)

    近段时间在搞定Lucene的一些问题,所以Heritrix源码分析暂时告一段落.今天下午在群里有同学提到了Heritrix异常终止的问题以及让Heritrix不停的抓取(就是抓完一遍后载入种子继续抓取 ...

  2. 漏洞都是怎么编号的CVE/CAN/BUGTRAQ/CNCVE/CNVD/CNNVD

    在一些文章和报道中常常提到安全漏洞CVE-1999-1046这样的CVE开头的漏洞编号,这篇文章将常见的漏洞ID的表示方法做下介绍: 1.以CVE开头,如CVE-1999-1046这样的 CVE 的英 ...

  3. android键盘事件

    在main.xml文件中代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  4. Facebook Architecture

    Facebook Architecture Quora article a relatively old presentation on facebook architecture another I ...

  5. (五)《Java编程思想》——final关键字

    可能使用final的三种情况:数据.方法.类. 1.final数据 final 常量必须是基本类型数据,且在定义时须赋值: 一个既是static又是final的域只占据一段不能改变的存储空间,只有一份 ...

  6. Head First HTML与CSS — 为你的页面加图像

    HTML中我们用img标签插入图像,在Web中常用的有三种:JPEG, PNG,GIF. 简单来讲,JPEG适合照片和复杂图像使用,而PNG或GIF适合单色图像.logo.和几何图形使用. JPEG: ...

  7. 《第一行代码》学习笔记35-服务Service(2)

    1.Android的UI线程不安全,想要更新应用程序里的UI元素,则须在主线程中进行,否则会出现异常. 2.Android不允许在子线程里进行UI操作,对于该情况,Android提供了一套异步消息处理 ...

  8. How to start the Virtualbox VMs under terminal

    Since we have servral machine on my testbed(fedora), and if I need start some VMs on that, I have to ...

  9. .NET MVC通过反射获取数据修改历史记录,并插入数据表中

    本文属于原创,转载时请标明出处! 折磨了我一个晚上的问题,奈何对物理的反射印象太深了,整天去想着物理的反射.折射怎么解.感谢少将哥哥给我的指点,经过一个晚上对反射的恶补,最终搞定了.纪念一下. 1.核 ...

  10. c3p0写连接池 Demo

    1.导包 2.配置文件:名称必须为:c3p0-config.xml,且必须放在src根目录下 <c3p0-config> <!-- 默认配置,有且仅可出现一次 ,如果没有指定则使用这 ...