【网络编程】之十三、ping程序实现
2023-09-27 14:22:35 时间
使用原始套接字:SOCK_RAW
需要ICMP
代码如下:
#include<iostream> #include<WinSock2.h> using namespace std; #pragma comment(lib, "WS2_32.lib") typedef struct icmp_hdr{ unsigned char icmp_type; unsigned char icmp_code; unsigned short icmp_checksum; unsigned short icmp_id; unsigned short icmp_sequence; unsigned long icmp_timnestamp; }ICMP_HDR, *PICMP_HDR; typedef struct _IPHeader{ UCHAR iphVerLen; UCHAR ipTOS; USHORT ipLength; USHORT ipID; USHORT ipFlags; UCHAR ipTTL; UCHAR ipProtocol; USHORT ipChecksum; ULONG ipSource; ULONG ipDestination; }IPHeader, *PIPHeader; USHORT checksum(USHORT* buffer, int size) { unsigned long cksum = 0; while(size > 1) { cksum += *buffer++; size -= sizeof(USHORT); } // 奇数,将最后一个字节扩展到双字, 再累加 if(size) cksum += *(UCHAR*)buffer; //高16 低16相加,取反 cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (USHORT)(~cksum); } int main(void) { char szDestIp[] = "127.0.0.1"; SOCKET sRaw= ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //SetTimeout(sRaw, 1000, TRUE); SOCKADDR_IN dest; dest.sin_family = AF_INET; dest.sin_port = htons(5674); dest.sin_addr.S_un.S_addr = inet_addr(szDestIp); char buff[sizeof(ICMP_HDR) + 32]; ICMP_HDR *pIcmp = (ICMP_HDR*)buff; pIcmp->icmp_type = 8; pIcmp->icmp_code = 0; pIcmp->icmp_id = (USHORT)::GetCurrentProcess(); pIcmp->icmp_checksum = 0; pIcmp->icmp_sequence = 0; memset(&buff[sizeof(ICMP_HDR)], 'E', 32); //发送 USHORT nSeq = 0; char recvBuf[1024]; SOCKADDR_IN from; int nLen = sizeof(from); while(TRUE) { static int nCount = 0; int nRet; if(nCount++ == 4) break; pIcmp->icmp_checksum = 0; pIcmp->icmp_timnestamp = ::GetTickCount(); pIcmp->icmp_sequence = nSeq++; pIcmp->icmp_checksum = checksum((USHORT*)buff, sizeof(ICMP_HDR) + 32); nRet = ::sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR*)&dest, sizeof(dest)); if(nRet == SOCKET_ERROR) { cout << "sendto error:" << ::WSAGetLastError() << endl; return -1; } nRet = ::recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen); if(nRet == SOCKET_ERROR) { if(::WSAGetLastError() == WSAETIMEDOUT) { cout << "time out" << endl; continue; } cout << "recvfrom failed:" << ::WSAGetLastError() << endl; return -1; } //解析 int nTick = ::GetTickCount(); if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR)) { cout << "Too few bytes from " << ::inet_ntoa(from.sin_addr) << endl; } ICMP_HDR *pRecvIcmp = (ICMP_HDR*)(recvBuf + sizeof(IPHeader)); if(pRecvIcmp->icmp_type != 0) { cout << "nonecho type " << pRecvIcmp->icmp_type << " recvd" << endl; return -1; } if(pRecvIcmp->icmp_id != ::GetCurrentProcessId()) { cout << "someone ele's packet!" << endl; return -1; } cout << nRet << " bytes from " << inet_ntoa(from.sin_addr) ; cout << "icmp_seq = " << pRecvIcmp->icmp_sequence ; cout << "time: " << nTick - pRecvIcmp->icmp_timnestamp << " ms"; cout << endl; Sleep(1000); } return 0; }
jofranks 13.7.24 于南昌
相关文章
- ubuntu server 18.04的安装 以及配置网络还有ssh服务
- 网络七层协议
- 复旦大学961-计算机系统基础-第五章-系统系I/O和网络编程
- [ kvm ] 三种基础网络模型创建及分析
- Linux网络编程(七)-第三方库-Libevent03:web服务器开发
- Linux网络编程(五)-Socket编程05:UDP客户端、服务端通信流程【①创建“报式”套接字/socket()、②绑定自己的IP与端口、③读/recvfrom()&写/sendto()、④关闭】
- 网络编程基础第一讲.网络模型
- IEEE1588精密网络同步协议(PTP)
- Altium Designer /DXP无网络铺铜:
- 网络I/o编程模型22 netty的源码总结
- 网络I/o编程模型17 netty框架实现心跳机制
- UNIX网络编程——网络I/O模型
- linux网络编程:splice函数和tee( )函数高效的零拷贝
- 叙利亚政府网络被黑,泄露43GB数据
- 5款能够进行网络问题扫描的安卓App
- altium designer21版中 设计规则添加多个网络
- 【源码】"拆" 网络请求库-Volley(上)
- 网络摄像头的地盘争夺战——四款僵尸软件的技术解析
- Windows网络编程
- 【Java笔记】网络编程
- 异构去堆叠 | 一种完美提升网络高可用SLA的方案
- POJ1149_PIGS(网络流/EK)
- ios之网络异常与正常视图的切换
- 这10个州是美国网络和系统管理员最佳选择
- 14.网络爬虫—selenium详讲
- Unix网络编程--卷一:套接字联网API
- 2018-2-13-win10-uwp-网络编程
- 网络编程:socket的阻塞模式和非阻塞模式