ping程序,在recvfrom时阻塞了,麻烦大虾们看看

csl312211865 2009-11-01 09:05:24
#include <iostream>
#include <windows.h>
using namespace std;

#define MAX_ICMP_PACKET_SIZE 1024
#define MAXBFRSIZE 2048
#define MAX_HOPS 30

typedef SOCKET* LPSOCKET;
typedef in_addr* LPINADDR;

typedef struct _IpHeader
{
unsigned int HeaderLength:4; //IP首部长度
unsigned int Version:4; //IP的版本
unsigned int TypeOfService; //服务类型
unsigned short TotalLength; //总的数据包大小
unsigned short Identification; //特殊标识符
unsigned char TTL; //Time To Live
unsigned char Protocol; //协议类型(TCP,UDP等)
unsigned short CheckSum; //校验和
unsigned int sourceIPAddress; //源地址
unsigned int destIPAddress; //目的地址
}IpHeader;

typedef IpHeader FAR* LPIpHeader;

#define IpHeaderLength sizeof(IpHeader)

typedef struct _IcmpHeader
{
unsigned char IcmpType; //ICMP报文类型
unsigned char IcmpCode; //ICMP代码
unsigned short IcmpCheckSum; //校验和
unsigned short IcmpId; //标识符
unsigned short IcmpSeq; //序列号
unsigned long IcmpTimestamp; //时间戳,非标准字段
}IcmpHeader;

typedef IcmpHeader FAR* LPIcmpHeader;

#define IcmpHeaderLength sizeof(IcmpHeader)

#define MAX_PACKET 2000 + IcmpHeaderLength
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 //最小为8字节的icmp包(仅包头)

int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return err;
}

if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup();
return -1;
}

cout << "ping " << endl;
string strIp = "";
// cin >> strIp;

SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(s == INVALID_SOCKET)
{
cout << "Create Socket Error!" << endl;
}

SOCKADDR_IN addrDest;
ZeroMemory(&addrDest, sizeof(addrDest));

addrDest.sin_addr.s_addr = inet_addr("127.0.0.1");
addrDest.sin_family = AF_INET;
addrDest.sin_port = htons(0);

char *buffer = new char[sizeof(IcmpHeader)+ 32];
IcmpHeader* icmp = (IcmpHeader *)(buffer);
// ZeroMemory(&icmp, sizeof(icmp));
icmp->IcmpType = 8;//回显请求类型
icmp->IcmpCode = 0;
icmp->IcmpId = GetCurrentProcessId();
icmp->IcmpCheckSum = 0;
icmp->IcmpSeq = 0;
icmp->IcmpTimestamp = GetTickCount();

memset(&icmp[sizeof(IcmpHeader)], '@', 32);

//计算校验和
unsigned long ulSum = 0;
unsigned short* pBuffer = (unsigned short*)(&icmp);
int nSize = sizeof(icmp);
for(int nIndex = 0; nSize > 1; nSize -= sizeof(short int), ++nIndex)
ulSum += pBuffer[nIndex];

if(nSize != 0)
{
ulSum += pBuffer[nIndex];
}

ulSum = (ulSum >> 16) + (ulSum & 0xFFFF);
ulSum += (ulSum >> 16);

icmp->IcmpCheckSum = (unsigned short)(~ulSum);
//发送ICMP数据报
int nSendResult = sendto(s, buffer, sizeof(IcmpHeader) + 32, 0, (sockaddr*)(&addrDest), sizeof(addrDest));

if(nSendResult == SOCKET_ERROR)
{
cout << GetLastError() << endl;
}

// Sleep(5000);

char *pRecvBuf = new char[MAX_ICMP_PACKET_SIZE];

sockaddr_in addrSend;
ZeroMemory(&addrSend, sizeof(addrSend));

addrSend.sin_family = AF_INET;
addrSend.sin_addr.s_addr = htonl(INADDR_ANY);
addrSend.sin_port = htons(0);

int nAddrSend = sizeof(addrSend);

// bind(s, (sockaddr*)&addrSend, sizeof(addrSend));

UINT nRecvLength = recvfrom(s, pRecvBuf, MAX_ICMP_PACKET_SIZE, 0, (sockaddr*)(&addrSend), &nAddrSend);

IcmpHeader *icmpRecv = (IcmpHeader*)pRecvBuf;

cout << icmpRecv->IcmpTimestamp;

WSACleanup();
return 0;
}
...全文
59 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ziplj 2009-11-01
  • 打赏
  • 举报
回复
晃得我不想看代码了...
csl312211865 2009-11-01
  • 打赏
  • 举报
回复
为什么网络这版块人这么少。。。自己顶

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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