【网络编程】之十三、ping程序实现
使用原始套接字: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 于南昌
【网络编程】之十三、ping程序实现的更多相关文章
- Socket网络编程--小小网盘程序(5)
各位好呀!这一小节应该就是这个小小网盘程序的最后一小节了,这一节将实现最后的三个功能,即列出用户在服务器中的文件列表,还有删除用户在服务器中的文件,最后的可以共享文件给好友. 列出用户在服务器中的文件 ...
- C#网络编程TCP通信实例程序简单设计
C#网络编程TCP通信实例程序简单设计 采用自带 TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服务端测试 ...
- Linux 网络编程基础(4) -- Ping 的C代码实现
1.背景 在进行网络编程的时候,通常使用的协议有TCP协议,UDP协议.这些协议在简历套接字之初需要制定套接字的类型,比如TCP应当设置为 SOCK_STREAM, UDP对应的套接字应当设置为SOC ...
- JAVA 网络编程 - 实现 群聊 程序
在实现 这个 程序之前, 我们 需要 了解 一些 关于 Java 网络 编程 的 知识. 基本 的 网络知识: 网络模型 OSI (Open System Interconnection 开放系统互连 ...
- UNIX网络编程---TCP客户/服务器程序示例(五)
一.概述 客户从标准输入读入一行文本,并写给服务器 服务器从网络输入读入这行文本,并回射给客户 客户从网络输入读入这行回射文本,并显示在标准输出上 二.TCP回射服务器程序:main函数 这里给了函数 ...
- python网络编程(十三)
协程-greenlet版 为了更好使用协程来完成多任务,python中的greenlet模块对其封装,从而使得切换任务变的更加简单 安装方式 使用如下命令安装greenlet模块: sudo pip ...
- Socket网络编程--小小网盘程序(1)
这个系列是准备讲基于Linux Socket进行文件传输.简单的文件传输就是客户端可以上传文件,可以从服务器端下载文件.就这么两个功能如果再加上身份验证,就成了FTP服务器了,如果对用户的操作再加上一 ...
- Socket网络编程--小小网盘程序(4)
在这一小节中实现了文件的下载,具体的思路是根据用户的uid和用户提供的文件名filename联合两张表,取得md5唯一标识符,然后操作这个标识符对应的文件发送给客户端. 实现下载的小小网盘程序 cli ...
- 第5章-unix网络编程 TCP/服务端程序示例
这一章主要是完成一个完整的tcp客户/服务器程序.通过一很简单的例子.弄清客户和服务器如何启动,如何终止,发生了某些错误会发生什么.这些事很重要的 客户端代码 #include "unp. ...
- 基于JAVA网络编程的聊天小程序
package com.neusoft.edu.socket; import java.io.BufferedReader; import java.io.IOException; import ja ...
随机推荐
- jquery如何判断checkbox(复选框)是否被选中 全选 反选
好长时间没用jq, 之前用的都是ng. 想着随便参考一下,结果被坑.因为这篇文章是09年的,也和当时jq的版本号有关,但是为什么在百度排名第一,百度果然坑人,以后还是google 给出坑人文章的链接 ...
- 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-TwinCAT自带的找原点功能块MC_Home怎么用
对于相对编码器类型轴(包括虚拟轴),可以使用贝福提供的找原点功能块MC_Home. HomingMode是指机器在往前跑的时候(30单位/s的默认速度),当碰到阻挡,则会有一个布尔值从FALSE改 ...
- Java8 更快的原子类:LongAdder(笔记)
更快的原子类:LongAdder 大家对AtomicInteger的基本实现机制应该比较了解,它们是在一个死循环内,不断尝试修改目标值,知道修改成功,如果竞争不激烈,那么修改成功的概率就很高 ...
- proto3 中的 map 类型
.proto syntax = "proto3"; option optimize_for = SPEED; message TestStruct { map<int32,s ...
- Android 自己定义控件开发入门(二)
上一次我们讲了一堆实现自己定义控件的理论基础.列举了View类一些能够重写的方法,我们对这些方法的重写是我们继承View类来派生自己定义控件的关键 我通过一个最简单的样例给大家展示了这一个过程,不管是 ...
- (一)Linux——Linux基本概念
Linux是一种自由和开放源码的类UNIX操作系统,使用Linux内核.目前存在着许多不同的Linux发行版,可安装在各种各样的电脑硬件设备,从手机.平板电脑.路由器和影音游戏控制台,到桌上型电脑,大 ...
- 转:nolock的替代方案-提交读快照隔离[行版本控制]
with(nolock)并意味着没有锁,实际上在查询一张表时,还是有锁,会对对象增加架构锁, 防止表会修改,会对数据库增加共享锁.若使用drop index,则要等到架构锁释放. sql serv ...
- webAPP开发的问题(总结)
自Iphone和Android这两个牛逼的手机操作系统公布以来,在互联网界从此就多了一个新的名词-WebApp(意为基于WEB形式的应用程序.执行在高端的移动终端设备). 开发人员们都知道在高端智能手 ...
- MongoDB安装、CURD增改查删操作、应用场景
NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL".非关系型的数据存储 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 ...
- fpga技能树