socket实现ping功能
来源:互联网 发布:用友u8数据库修复工具 编辑:程序博客网 时间:2024/06/10 08:55
#include <winsock2.h>#include <iostream>#include <windows.h>using namespace std;#define DATA_SIZE 32#define RECV_MAX_SZIE 1024#pragma comment(lib, "ws2_32.lib")typedef struct tag_icmphdr //icmp头{ unsigned char icmp_type; unsigned char icmp_code; unsigned short icmp_checksum; unsigned short icmp_id; unsigned short icmp_sequence;} ICMPHDR, *PICMPHDR;typedef struct tag_iphdr //ip头{ UCHAR iphVerLen; UCHAR ipTOS; USHORT ipLength; USHORT ipID; USHORT ipFlags; UCHAR ipTTL; UCHAR ipProtacol; USHORT ipChecksum; ULONG ipSource; ULONG ipDestination;} IPHDR;USHORT CheckSum(USHORT *buf,int size){ 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 FillIcmp(PICMPHDR p){ p->icmp_type = 8; p->icmp_code = 0; p->icmp_checksum = 0; p->icmp_id = (unsigned short)::GetCurrentProcessId(); p->icmp_sequence = 0;}int main(){ WORD version = MAKEWORD(2,2); WSADATA data; WSAStartup(version, &data); if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2) { cout << "WSAStartup failed" << endl; WSACleanup(); return -1; } char host[] = "www.baidu.com"; struct hostent *he = gethostbyname(host); if (!he) { return -1; } struct in_addr **addr_list = (struct in_addr **) he->h_addr_list; SOCKADDR_IN addr; //目标主机地址 addr.sin_family = AF_INET; addr.sin_addr = *addr_list[0]; addr.sin_port = htons(0); SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //创建原始套接字 int outTime = 1000; int rst; rst = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&outTime, sizeof(int)); //设置发送超时 if (SOCKET_ERROR == rst) { cout << "setsockopt erro" << endl; closesocket(sock); WSACleanup(); return -1; } rst = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&outTime, sizeof(int)); //设置接收超时 if (SOCKET_ERROR == rst) { cout << "setsockopt erro" << endl; closesocket(sock); WSACleanup(); return -1; } char *icmp = (char*)malloc(sizeof(ICMPHDR)+DATA_SIZE); //为icmp包申请内存 memset(icmp, 0, sizeof(ICMPHDR)+DATA_SIZE); //内存空间置零 PICMPHDR picmp = (PICMPHDR)icmp; FillIcmp(picmp); //填充icmp包 unsigned short sequence = 0; //序列号 int count = 4; //发送请求次数 char recvbuf[RECV_MAX_SZIE]; //接收buf SOCKADDR_IN addrfrom; //接收地址 int len = sizeof(SOCKADDR); //地址大小 int ipTTL = 0; //TTL while (count--) { picmp->icmp_checksum = 0; picmp->icmp_sequence = sequence++; picmp->icmp_checksum = CheckSum((USHORT*)icmp, sizeof(ICMPHDR)+DATA_SIZE); DWORD send_ts = ::GetTickCount(); int result; result = sendto(sock, icmp, sizeof(ICMPHDR)+DATA_SIZE, 0, (SOCKADDR*)&addr, sizeof(SOCKADDR)); //向目标主机发送icmp请求包 if (SOCKET_ERROR == result) { if (WSAETIMEDOUT == WSAGetLastError()) { cout << "time out" << endl; continue; } else { cout << "sendto error" << endl; closesocket(sock); WSACleanup(); return -1; } } while ((result = recvfrom(sock, recvbuf, RECV_MAX_SZIE, 0, (SOCKADDR*)&addrfrom, &len)) > 0) { if (addr.sin_addr.s_addr == addrfrom.sin_addr.s_addr) { break; } } if (SOCKET_ERROR == result) { if (WSAETIMEDOUT == GetLastError()) { cout << "time out" << endl; continue; } else { cout << "recvform error" << endl; closesocket(sock); WSACleanup(); return -1; } } DWORD recv_ts = ::GetTickCount(); if (result < sizeof(IPHDR) + sizeof(ICMPHDR) + DATA_SIZE) { cout << "too few bytes" << endl; } IPHDR *pIP = (IPHDR*)recvbuf; ipTTL = (int)pIP->ipTTL; //获取目标主机TTL PICMPHDR p = (PICMPHDR)(recvbuf+sizeof(IPHDR)); if (p->icmp_type != 0) { cout << "error type " << p->icmp_type << " receved" << endl; return -1; } cout << "reply from: " << inet_ntoa(addrfrom.sin_addr) << " time: " << recv_ts - send_ts << "ms" << " TTL=" << ipTTL << endl; } getchar(); return 0;}
0 0
- socket实现ping功能
- Socket API实现PING
- socket实现Ping命令
- java 实现ping功能
- c#实现ping功能
- Java 实现Ping功能
- java实现ping功能
- Java 实现Ping功能
- java实现ping功能
- Java 实现Ping 功能
- Android实现ping功能
- 实现Ping功能
- java 实现Ping功能
- C++实现ping功能
- C++实现Ping功能
- ping功能实现(ICMP)
- ping功能实现
- socket实现ping命令(控制台)
- 单例程 饿汉式 懒汉式
- txt转换pdf的实用方法分享
- 工作日志-20151012
- 雪花效果实现
- [Android Studio 权威教程]打包、生成jks密钥、签名Apk、多渠道打包
- socket实现ping功能
- MongoDB——第一天 基础入门
- 处理积分加现金支付业务逻辑
- ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]
- android开发中关于PendingIntent的知识点
- Linux -Qt 开发环境搭建
- 解读Unity中的CG编写Shader系列1——初识CG
- handler底层是如何将消息从子线程发送到主线程
- 二分查找