Socket程式設計之ping程式的實現

2021-07-09 08:03:38 字數 3956 閱讀 3425

標頭檔案部分:

/*導入庫檔案*/

#pragma comment( lib, "ws2_32.lib" )

/*載入標頭檔案*/

#include //建立套接字頭檔案

#include #include #include #include #include #include #include using namespace std;

/*定義常量*/

/*表示要記錄路由*/

#define ip_record_route 0x7

/*預設資料報大小*/

#define def_packet_size 32

/*最大的icmp資料報大小*/

#define max_packet 1024

/*最大ip頭長度*/

#define max_ip_hdr_size 60

/*icmp報文型別,回顯請求*/

#define icmp_echo 8

/*icmp報文型別,回顯應答*/

#define icmp_echoreply 0

/*最小的icmp資料報大小*/

#define icmp_min 8

/*自定義函式原型*/

void init_ping();

void userhelp();

void getargments(int argc, char** argv);

ushort checksum(ushort *buffer, int size);

void fillicmpdata(char *icmp_data, int datasize);

void freeres();

void decodeipoptions(char *buf, int bytes); //ip報文各欄位解析

void decodeicmpheader(char *buf, int bytes, sockaddr_in* from); //icmp報文首部解析翻譯

void pingtest(int timeout); //ping命令測試程式

void pinginput(int &argc,char *argv);

/*ip報頭字段資料結構*/

typedef struct _iphdr //宣告定義乙個結構體,用來表示ip首部

ipheader;

/*icmp報頭字段資料結構*/

typedef struct _icmphdr //同上,這裡表示icmp報文的首部:用資料結構表示

icmpheader;

/*ip選項頭欄位資料結構*/

typedef struct _ipoptionhdr //表示ip首部中的可選字段

ipoptionheader;

socket m_socket;

ipoptionheader ipoption;

sockaddr_in destaddr;

sockaddr_in sourceaddr;

char *icmp_data;

char *recvbuf;

ushort seq_no ; //typedef unsigned short ushort;

char *lpdest; //lpdest表示目的位址的指標

int datasize;

bool recordflag;

double packetnum;

bool inputtrue;

int rcount;

原始檔部分:

#include"ping.h"

/*初始化變數*/

void init_ping()

else}}

/*引數是資料報大小或者ip位址*/

else if (isdigit(argv[i][0])) //判斷是否為數字

if (size)

while(cksum>>16)

cksum = (cksum>>16) + (cksum & 0xffff); //兩次就夠了,就能保證高16位為全0

return (ushort)(~cksum); //最後的二進位制反碼和再取反賦值給檢驗和字段

}/*填充icmp資料報欄位*/

void fillicmpdata(char *icmp_data, int datasize)

/*釋放資源*/

void freeres()

/*解讀ip選項頭*/

void decodeipoptions(char *buf, int bytes)

/*核實收到的id號和傳送的是否一致*/

if (icmphdr->i_id != (ushort)getcurrentprocessid()) //getcurrentprocessid返回當前程序的pid

{cout<

cout<

cout

/*將獲取到的位址族值賦給目的地位址中的相應字段*/

destaddr.sin_family = hp->h_addrtype;

cout<

/*獲取作業系統啟動到現在所經過的毫秒數,設定時間戳*/

((icmpheader*)icmp_data)->timestamp = gettickcount();

/*設定序列號*/

((icmpheader*)icmp_data)->i_seq = seq_no++;

/*計算校驗和*/

((icmpheader*)icmp_data)->i_cksum = checksum((ushort*)icmp_data, datasize);

/*基於udp開始傳送icmp請求*/ //設定目的套接字的位址資訊,位址結構體的長度

writenum = sendto(m_socket, icmp_data, datasize, 0,(struct sockaddr*)&destaddr, sizeof(destaddr));

//設定0那個位置的值,將會影響sendto函式呼叫的行為

/*如果傳送不成功*/

if (writenum == socket_error)

{if (wsagetlasterror() == wsaetimedout) //傳送超時

{cout<

{ cout

init_ping();

pinginput(argc,argv);

getargments(argc, argv);

if(inputtrue)

continue;

if(!lpdest)

{ cout<

程式執行測試:

測試路由功能:

測試路由和ping功能:

補充:部分網路環境可能禁止 記錄路由功能,同時,我們的程式是 基於visual c++ 6.0開發環境的,其他開發環境需要做相應標頭檔案包括的更改;程式的執行 需要提供 "管理員許可權" ;否則會報 1013 的錯誤。

//寫的不好的話,還請大家多給點建議。

socket程式設計之點對點聊天程式

p2psrv.c include include include include include include 解決父程序退出,子程序不退出 include include include include define err exit m do while 0 void handler int ...

網路程式設計之Socket程式設計

對 tcp ip udp socket 程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問 1.什麼是tcp ip udp?2.socket在 呢?3.socket是什麼呢?4.你會使用它們嗎?什麼是tcp ip udp?tcp ip transmission co...

網路程式設計之socket程式設計

大多數專案是在linux下開發伺服器端,而在windows下開發客戶端,需要經常在兩大平台之間進行切換,單獨學習一種平台沒有實踐意義。值得欣慰的是,兩大平台下的 socket 程式設計非常相似,並不會增加多少學習成本。網路程式設計就是編寫程式使兩台聯網的計算機相互交換資料。這就是socket的全部內...