网络编程 ping程序有点问题,求大神帮忙看看

问题描述

网络编程 ping程序有点问题,求大神帮忙看看

// ping.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include
#pragma comment(lib,"ws2_32")

//定义ICMP首部
typedef struct icmp_hdr{
unsigned char icmp_type; //ICMP消息类型,回显请求:8,回显应答请求:0
unsigned char icmp_code; //代码,代码域进一步定义了请求或消息的类型
unsigned short icmp_checksum;//校验和
//下面是回显头
unsigned short icmp_id; //ICMP数据报的ID号;用来唯一标识此请求的ID号,通常设为进程ID
unsigned short icmp_sequence;//ICMP数据报的序列号
unsigned long icmp_timestamp;//时间戳,可选数据部分,可以忽略
}ICMP_HDR; ///

struct IpHeader {
BYTE HeaderLength; //首部长度
BYTE Version; //版本
BYTE DS; //区分服务
WORD TotalLength; //总长度
WORD ID; //标识
BYTE FragmentOffset0; //片偏移
BYTE MF; //MF标识
BYTE DF; //DF标识
BYTE Reserved; //保留标识
BYTE FragmentOffset1; //片偏移
BYTE TTL; //生存时间
BYTE Protocol; //协议
WORD Checksum; //检验和
DWORD SourceAddress; //源地址
DWORD DestinationAddress;//目的地址
};

USHORT checksum(USHORT* buffer, int size) //计算校验和
{
ULONG cksum = 0;

while (size > 1) {          //将数据以字为单位累加到cksum中
    cksum += *buffer++;
    size -= sizeof(USHORT);
}
if (size) {                 //如果数据长度为奇数,最后一个字节将被扩展到字,累加的结果是一个双字
    cksum += *(UCHAR*)buffer;
}

cksum = (cksum >> 16) + (cksum & 0xFFFF);//将双字的高16位于低16位相加
cksum += (cksum >> 16);
return (USHORT)(~cksum);    //最后取反得到校验和

}

int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested = MAKEWORD(1, 1);
WSADATA wsaData;

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

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

char* szDestIp = "127.0.0.1";  //目标IP地址,即要Ping的IP地址

SOCKET sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //创建原始套接字

SOCKADDR_IN dest;   //设置目的地址
dest.sin_family = AF_INET;
dest.sin_addr.S_un.S_addr = inet_addr(szDestIp);
dest.sin_port = htons(0);

char buff[sizeof(ICMP_HDR)+32]; //创建ICMP封包
ICMP_HDR* pIcmp = (ICMP_HDR*)buff;
//下面填写ICMP封包数据
pIcmp->icmp_type = 8;//请求一个ICMP回显
pIcmp->icmp_code = 0;
pIcmp->icmp_checksum = 0;
pIcmp->icmp_id = (USHORT)GetCurrentProcessId();//GetCurrentProcessId:获取当前进程的一个唯一标识符
pIcmp->icmp_sequence = 0;
memset(buff, 'E', 32);//填充数据部分,可以为任意

int timeout = 1000;     //设置接收超时处理
int _break = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
if (_break == SOCKET_ERROR){
    fprintf(stderr, "failed to set timeout:%dn", WSAGetLastError());
}

if (bind(sockRaw, (sockaddr*)&dest, sizeof(dest)) == SOCKET_ERROR) {
    printf("bind error!n");
    return 0;
}

//开始发送和接收ICMP封包
USHORT Seq = 0;
char recvBuf[1024];
SOCKADDR_IN from;
int Len = sizeof(from);

while (1) {
    static int Count = 0;
    int Ret;
    if (Count++ == 4)   break;
    pIcmp->icmp_checksum = 0;
    pIcmp->icmp_timestamp = GetTickCount();
    pIcmp->icmp_sequence = Seq++;
    pIcmp->icmp_checksum = checksum((USHORT*)buff, sizeof(ICMP_HDR) + 32);

    Ret = sendto(sockRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR*)&dest, sizeof(dest));
    if (Ret == SOCKET_ERROR) {
        printf("sendto() failed:%dn", WSAGetLastError);
        return -1;
    }

    Ret = recvfrom(sockRaw, recvBuf, 1024, 0, (SOCKADDR*)&from, &Len);
    if (Ret == SOCKET_ERROR) {
        if (WSAGetLastError() == WSAETIMEDOUT) {
            printf("timed outn");
            continue;
        }
        printf("recvfrom() failed:%dn", WSAGetLastError());
        return -1;
    }

    //开始解析接收到的ICMP
    int Tick = ::GetTickCount();
    if (Ret < sizeof(IpHeader) + sizeof(ICMP_HDR))
        printf("too few bytes from %sn", inet_ntoa(from.sin_addr));
    ICMP_HDR* pRecvIcmp = (ICMP_HDR*)(recvBuf + sizeof(IpHeader));
    if (pRecvIcmp->icmp_type != 0) {//回显
        printf("nonecho type %d recvdn", pRecvIcmp->icmp_type);
        return -1;
    }
    if (pRecvIcmp->icmp_id != GetCurrentProcessId()) {
        printf("someone else's packet!n");
        return -1;
    }

    printf("%d bytes from %s:", Ret, inet_ntoa(from.sin_addr));
    printf("icmp_seq = %d , ", pRecvIcmp->icmp_sequence);
    printf("time: %d msn", Tick - pRecvIcmp->icmp_timestamp);
    Sleep(1000);
}

return 0;

}

解决方案

上面的是在VS2015上运行的,在VS2013上运行的结果还不一样

解决方案二:

解决方案三:

你ping的是127.0.0.1啊,超时了

时间: 2024-09-30 02:55:33

网络编程 ping程序有点问题,求大神帮忙看看的相关文章

android-Android程序崩溃,求大神帮忙看看这是什么原因

问题描述 Android程序崩溃,求大神帮忙看看这是什么原因 如题,代码中没错误,但是每次运行到那个方法就自动退出了.这是Logcat中的error列表,谁知道是什么原因? 04-22 15:29:54.788: E/dalvikvm(3610): threadid=11: created from interp,name=Thread-3687 04-22 15:29:54.798: E/dalvikvm(3610): threadid=11: calling run(),name=Threa

嵌入式-cgi登陆程序出错,求大神帮忙

问题描述 cgi登陆程序出错,求大神帮忙 在linux下登陆arm开发板,用html和cgi写登陆程序.点击登陆后,浏览器显示the connection was reset,但是网址也调到了cgi程序的路径.程序应该是没错的.希望各位大神帮帮忙,分析一下到底是哪里出问题了,感激不尽.

我是菜鸟,在c++编程中遇到问题,求大神帮忙

问题描述 我是菜鸟,在c++编程中遇到问题,求大神帮忙 对于这个题目: 定义一个基类Person,数据成员包含字符指针类型变量Name用于保存姓名, 函数成员包括默认构造函数.带形参构造函数用于初始化数据成员.输出 姓名的成员函数PrintName().从Person类派生出Student类,增加长整型 数据成员Number用于保存学号,派生类的函数成员包括带形参构造函数用 于初始化数据成员,输出学生信息的成员函数PrintInfo(). 要求:在函数PrintInfo()中需要调用基类的成员函

unix网络编程-关于线程问题,求大神们帮帮忙

问题描述 关于线程问题,求大神们帮帮忙 void *task(void *p) {} pthread_create(&id, 0, task, (void *)i); 中的(void *)i是什么意思??? 解决方案 就是把这个指针转换成void * 因为pthread_create为了通用的考虑,最后一个参数要求是void *,而不是int *.为了通过编译,必须这么做. 如果参数是int *,就不通用了.你这里能传了,但是如果要传char,float等等就不行了.所以定义成void *的.

mfc-编程问题,小白女子求大神帮忙【哭】着急,在线等,感激不尽

问题描述 编程问题,小白女子求大神帮忙[哭]着急,在线等,感激不尽 有一个MFC工程,我用VS编译通过但是没有窗口,而用VC编译不能通过%>_<%求大神帮忙把程序运行起来····· 好人一生平安······跪求时间充裕有耐心的大神帮忙[跪]~ 解决方案 看看是sln/vcproj还是dsp/dsw,前者用VS,后者用VC 解决方案二: 问题本身就不清楚 解决方案三: 问题本身就不清楚 解决方案四: 没法帮你,能不能详细一点, 解决方案五: 你的程序是用 VC++开发的?开发环境是VS2010?

list-编程白痴一位,求大神帮忙 , jsp左右框

问题描述 编程白痴一位,求大神帮忙 , jsp左右框 box 1 box 2 名字1 名字1 名字2 名字2 名字3 名字3 名字4 名字5 全选 反选 全选 反选

编程-新人有个关于ppl并行程序问题,求大神解答

问题描述 新人有个关于ppl并行程序问题,求大神解答 我用VC2010编程,程序里面用了ppl并行处理,调用了下parallel_for_each. 但是移植到其他没有安装VC的电脑上程序就不能运行了,在运行过程中产生错误: "this application has requested the runtime to terminate it in an unusual way." 我是做影像畸变矫正,程序移植后可以处理几张影像,然后就弹出终止程序的消息 如果我才用单线程的程序就可以处

编程-有一个小程序急用,但是我不会编译,求大神帮忙编译啊~~~太感谢!!

问题描述 有一个小程序急用,但是我不会编译,求大神帮忙编译啊~~~太感谢!! 如题,是一个小程序,用的是自己的makefile,下载下来了但是不会编译啊~~~~要exe格式的,那位大神可以帮忙编译出来真是太感激不尽!或者教一下我~~~太感谢了!编译好请发zhaojialiangsuper@126.com~源码地址 源码:https://releases.stm32flash.googlecode.com/git/stm32flash-0.4.tar.gz 解决方案 http://download

编程c语言-这个程序详细分析~~~求大神

问题描述 这个程序详细分析~~~求大神 看了半天弄不清 解决方案 这是一个函数递归调用的例题,首先n=5,调用age函数,此时n!=1,所以直接执行else语句,t=age(4)+2,(age(4)的值等于age(3)+2)n=4>1,第二次调用age函数,再次执行else语句,返回的是t=age(3)+2,(age(2)+2)以此类推,当第五次调用age函数时,n==1,所以第五次返回的是10,所以最终的结果是10+2+2+2+2=18. 解决方案二: 总共有4层递归,最深的一层递归时n=1,