自己實現(xiàn)一個ping程序

小時候不太會玩電腦,一般自己玩的時候流程是:開始--附加功能--游戲與娛樂。
倘若旁邊有妹子在圍觀,我便會win+R-----cmd----ping baidu.com.然后看著屏幕上跳出一行行數(shù)字,假裝自己看得懂的樣子,過一會兒再慢悠悠地打開太空彈球玩起來
現(xiàn)在想起來真的是圖樣圖森破,甚至還非常naive啊。
這個ping程序算是我對計算機(jī)最早的認(rèn)識了,作為一個生活在圖形界面時代的人類,這也是我第一次知道了命令行形式的人機(jī)交互。
之前學(xué)習(xí)了計算機(jī)網(wǎng)絡(luò)的知識,知道了它的原理其實是利用ICMP協(xié)議的回顯請求來實現(xiàn)的,通過構(gòu)造ICMP報文向目的主機(jī)發(fā)出,然后接收返回報文,計算經(jīng)過的時間,就能計算出主機(jī)到目的主機(jī)之間的RTT(Round Trip Time),也就是我們平時講的延遲。
由于ICMP工作在網(wǎng)絡(luò)層,不能保證交付,也不保證順序,所以發(fā)送多個請求的時候,可能會出現(xiàn)亂序的情況,于是ping程序中在數(shù)據(jù)段保存包本身的發(fā)送時間,接收到之后用系統(tǒng)時間減去報文中讀取的時間即可得到RTT。為了簡化過程,我在此只發(fā)送一個報文。
要構(gòu)造ICMP包,首先要知道其格式,
Type (8bit) | Code(8bit) | Checksum (16bit) | Identifier (16bit) | Sequence Number (16bit) | Data ...
我么要用到的是回顯請求,對應(yīng)type是8,code是0,checksum要通過特定的算法獲得,其他部分自己處理即可。

import socket
import  array,struct,time,select
def checksum(data):
if(len(data)%2!=0):
    data+=b'\x00'
a=array.array('H',data)
s=0
for d in a:
    s=s+d
s=(~s)&0xffff
return s

這段代碼將已經(jīng)除checksum以外其它打包好的數(shù)據(jù)進(jìn)行一系列計算,得到一個16bit的數(shù),用于差錯檢測,如果計算錯誤,服務(wù)器方不會響應(yīng),你也就接受不到響應(yīng)的報文了。在編寫網(wǎng)絡(luò)程序的時候,調(diào)試時要利用抓包工具查看自己發(fā)出的報文的具體內(nèi)容,否則難以得知自己錯在何處。

def send_packet(my_socket,destination_addr):
header=struct.pack('bbHh',8,0,1,1)
data=0
data=struct.pack('d',data)
checks=checksum(header+data)
packet=struct.pack('bbHHh',8,0,checks,1,1)+data
my_socket.sendto(packet,(destination_addr,1))
t=recive_ping(my_socket, 5)
print(t)

def recive_ping(my_socket,timeout):
timeleft=timeout
while True:
    starttime=time.time()
    select_=select.select([my_socket],[],[],timeleft)
    if select_[0]==[]:
        print("timeout")
        return -1
    t=time.time()-starttime
    return  t

這兩個函數(shù)一起完成了報文的構(gòu)造和發(fā)送,這其中用到了raw類型socket,select用于接收數(shù)據(jù),由于數(shù)據(jù)要翻譯成二進(jìn)制發(fā)送,直接連接字符串肯定是不行的,所以要用struct將數(shù)據(jù)打包。

def do(addr):
icmp=socket.getprotobyname('icmp')
s=socket.socket(socket.AF_INET,socket.SOCK_RAW,icmp)
send_packet(s, addr)

do("220.181.57.217")

這就是程序的入口了,運行效果就不貼了,反正就是打印出一個浮點數(shù)。數(shù)字的含義是延遲時間(實際是rtt)。

與ping相似的另一個traceroute,實現(xiàn)原理也類似,它利用的是ip頭部的TTL,通過構(gòu)造指向目的主機(jī)的ttl從1遞增的數(shù)據(jù)包,就能獲得源主機(jī)到目的主機(jī)之間所有經(jīng)過的路由,這可以在網(wǎng)上找到不少資料,此處不再贅述。

參考:[1]:https://bbs.ichunqiu.com/thread-8970-1-1.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.這篇文章不是本人原創(chuàng)的,只是個人為了對這部分知識做一個整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,352評論 6 174
  • 個人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,185評論 0 8
  • nmap使用指南(終極版) 原創(chuàng)2017-09-09hl0rey信安之路 一、目標(biāo)指定 1.CIDR標(biāo)志位 192...
    用電熱毯烤豬閱讀 12,150評論 1 49
  • 7.1 引言 “ping”這個名字源于聲納定位操作。Ping程序由Mike Muuss編寫,目的是為了測試另一臺主...
    張芳濤閱讀 1,787評論 0 2
  • 人認(rèn)為自己應(yīng)當(dāng)采取一種行動,這種行動可以稱作公道、正當(dāng)、道德、自然法,這種正當(dāng)行為的念頭常??M繞在人的腦際。 人知...
    蘇曼青閱讀 442評論 0 1

友情鏈接更多精彩內(nèi)容