首先建立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...