模擬ICMP過程

2021-07-09 01:34:02 字數 3224 閱讀 5212

首先建立common標頭檔案

//

// comm.h檔案

// 包含一些公共函式

#ifndef __comm_h__

#define __comm_h__

// 校驗和的計算

// 以16位的字為單位將緩衝區的內容相加,如果緩衝區長度為奇數,

// 則再加上乙個位元組。它們的和存入乙個32位的雙字中

ushort checksum(ushort* buff, int size);

bool setttl(socket s, int nvalue);

bool settimeout(socket s, int ntime, bool brecv = true);

#endif // __comm_h__

然後建立資料報頭頭檔案

//

// protoinfo.h檔案

/*定義協議格式

定義協議中使用的巨集

*/#include #ifndef __protoinfo_h__

#define __protoinfo_h__

#define ethertype_ip 0x0800

#define ethertype_arp 0x0806

typedef struct _etheader // 14位元組的以太頭

etheader, *petheader;

#define arphrd_ether 1

// arp協議opcodes

#define arpop_request 1 // arp 請求

#define arpop_reply 2 // arp 響應

typedef struct _arpheader // 28位元組的arp頭

arpheader, *parpheader;

// 協議

#define proto_icmp 1

#define proto_igmp 2

#define proto_tcp 6

#define proto_udp 17

typedef struct _ipheader // 20位元組的ip頭

ipheader, *pipheader;

// 定義tcp標誌

#define tcp_fin 0x01

#define tcp_syn 0x02

#define tcp_rst 0x04

#define tcp_psh 0x08

#define tcp_ack 0x10

#define tcp_urg 0x20

#define tcp_ace 0x40

#define tcp_cwr 0x80

typedef struct _tcpheader // 20位元組的tcp頭

tcpheader, *ptcpheader;

typedef struct _udpheader

udpheader, *pudpheader;

#endif // __protoinfo_h__

common.cpp

//

// comm.cpp檔案

#include #include "ws2tcpip.h"

#include "common.h"

#include ushort checksum(ushort* buff, int size)

// 是奇數

if(size)

// 將32位的chsum高16位和低16位相加,然後取反

cksum = (cksum >> 16) + (cksum & 0xffff);

cksum += (cksum >> 16);

return (ushort)(~cksum);

}bool setttl(socket s, int nvalue)

bool settimeout(socket s, int ntime, bool brecv)

最後是主檔案,接受icmp回送應答報文。type為0  code為0

///

// ping.cpp檔案

#include "protoinfo.h"

#include "common.h"

#include #include typedef struct icmp_hdr

icmp_hdr, *picmp_hdr;

int main()

nret = ::recvfrom(sraw, recvbuf, 1024, 0, (sockaddr*)&from, &nlen);

if(nret == socket_error)

printf(" recvfrom() failed: %d\n", ::wsagetlasterror());

return -1;

} // 下面開始解析接收到的icmp封包

int ntick = ::gettickcount();

if(nret < sizeof(ipheader) + sizeof(icmp_hdr))

// 接收到的資料中包含ip頭,ip頭大小為20個位元組,所以加20得到icmp頭

// (icmp_hdr*)(recvbuf + sizeof(ipheader));

icmp_hdr* precvicmp = (icmp_hdr*)(recvbuf + 20);

if(precvicmp->icmp_type != 0) // 回顯

if(precvicmp->icmp_id != ::getcurrentprocessid())

printf("從 %s 返回 %d 位元組:\n", inet_ntoa(from.sin_addr),nret);

printf(" 資料報序列號 = %d. \t", precvicmp->icmp_sequence);

printf(" 延時大小: %d ms\n", ntick - precvicmp->icmp_timestamp);

printf(" \n");

// 每一秒傳送一次就行了

::sleep(1000);

} return 0;

}

ICMP協議和ICMP協議

一 icmp協議 因為ip協議不提供可靠的傳輸服務,也不提供端到端或點到點的確認,如果出錯可以通過icmp報告來看,它是在ip模組中實現。tcp ip協議設計的icmp協議就是為了彌補ip協議的不足。它是tcp ip協議族的乙個子協議,用於在ip主機 路由器之間傳遞控制訊息。控制訊息指網路通不通 主...

選擇排序過程模擬

選擇排序是一種簡單直觀的排序演算法。它的工作原理很容易理解 初始時在序列中找到最小 大 元素,放到序列的起始位置作為已排序序列 然後,再從剩餘未排序元素中繼續尋找最小 大 元素,放到已排序序列的末尾。以此類推,直到所有元素均排序完畢 可以使用for迴圈完成操作 include include inc...

模擬燒茶的過程

模擬燒茶的過程 1 燒水 2 需要茶葉的時候發現沒茶葉,叫eric去買 沒有茶葉,需要買 3 需要杯子的時候發現沒杯子,叫meten去買 沒有杯子,需要買 4 放茶葉 3 倒水 public class execdemo2 共享資料tea author administrator class tea...